2 Power meters combine to one led pulse

Okee, i tried the following:

//Number of pulses, used to measure energy.
volatile byte pulseCount = 0;

const byte Meter1Pin = D1; // External Interrupt Pin
const byte Meter2Pin = D2; // External Interrupt Pin
const byte LEDPin = LED_BUILTIN; // Pin D4

void onPulse()
{
  pulseCount++;
}

void setup()
{
  pinMode (Meter1Pin , INPUT_PULLUP);
  pinMode (Meter2Pin , INPUT_PULLUP);
  // KWH interrupts attached to external interrupts
  attachInterrupt(digitalPinToInterrupt(Meter1Pin), onPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(Meter2Pin), onPulse, FALLING);
}

void loop()
{
  bool pulse = false;

  noInterrupts();
  if (pulseCount > 0)
  {
    pulse = true;
    pulseCount--;
  }
  interrupts();

  if (pulse)
  {
    // LED pulse rate is limited to 50 pulses per second, max. 
    // = 50 Wh per second
    // = 3000 Wh per minute
    // = 180 kWh per hour
    // = 180 kW
    // = over 800 Amps at 220 Volts, 1600 Amps at 110 Volts
   // Should be fast enough for any home system
    digitalWrite(LEDPin, HIGH);
    delay(10);
    digitalWrite(LEDPin, LOW);
    delay(10);
  }
}

Same behavior. The led is flashing.
I uploaded the code to another board. A D1 mini. Same behavior.
I don’t have a real arduino. Maybe I have to buy one.
There is nothing connected to de board, yet.

Wich arduino board do you recommend?

Edit: I have got a Teensy LC. Maybe i can try this board. Wich pins do I have to use?

Two pins that support External Interrupts. I don’t know enough about the Teensy LC to know what it supports.

If you want to test a sketch for Arduino compatibility, the gold standard is the Arduino UNO R3. You could also use the Arduino MEGA R3. If you ever need help, be sure to say what model you are using.

I’m on my way…
This blink script is working. The led is on pin 13 by a Teensy LC:

void setup()
{
  pinMode(13, OUTPUT);       // LED
  pinMode(7, INPUT_PULLUP); // Pushbutton
}

void loop()
{
  if (digitalRead(7)) {
    // D7 pin is high due to pullup resistor
    digitalWrite(13, LOW);   // LED on
    delay(400);                  // Slow blink
    digitalWrite(13, HIGH);  // LED off
    delay(400);
  } else {
    // D7 pin is low due to pushbutton pressed
    digitalWrite(13, LOW);   // LED on
    delay(80);                   // Fast blink
    digitalWrite(13, HIGH);  // LED off
    delay(80);
  }
}

All of the pins have a pullup resistor which may be activated when the pin is an input. Just use pinMode() with INPUT_PULLUP.
pinMode(PIN_D7, INPUT_PULLUP);
Source: Digital Input/Output on Teensy with Arduino functions, digitalWrite, digitalRead, pinMode

So I change the script:

//Number of pulses, used to measure energy.
volatile byte pulseCount = 0;

const byte Meter1Pin = 0; // External Interrupt Pin
const byte Meter2Pin = 1; // External Interrupt Pin
const byte LEDPin = 13; // led is pin 13

void onPulse()
{
  pulseCount++;
}

void setup()
{
  pinMode (Meter1Pin , INPUT_PULLUP);
  pinMode (Meter2Pin , INPUT_PULLUP);
  pinMode(LEDPin, OUTPUT);       // LED
  // KWH interrupts attached to external interrupts
  attachInterrupt(digitalPinToInterrupt(Meter1Pin), onPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(Meter2Pin), onPulse, FALLING);
}

void loop()
{
  bool pulse = false;

  noInterrupts();
  if (pulseCount > 0)
  {
    pulse = true;
    pulseCount--;
  }
  interrupts();

  if (pulse)
  {
    // LED pulse rate is limited to 50 pulses per second, max. 
    // = 50 Wh per second
    // = 3000 Wh per minute
    // = 180 kWh per hour
    // = 180 kW
    // = over 800 Amps at 220 Volts, 1600 Amps at 110 Volts
   // Should be fast enough for any home system
    digitalWrite(LEDPin, HIGH);
    delay(10);
    digitalWrite(LEDPin, LOW);
    delay(10);
  }
}

The led is off. That’s good :slight_smile:
But when I connect pin 0 or pin 1 to 3.3V the led stays off.

That is what you told it to do. The input has a PULLUP resistor to keep it HIGH when it is not connected. The interrupt is set for FALLING, meaning interrupt when the pin goes from HIGH to LOW. Connecting the pin to 3.3V is NOT going to make it read LOW. Connect it to Ground.

Haha oeps :slight_smile:

When I connect it to ground the led stays dark.
There is 3.3v on pin 0 to ground and pin 1 to ground.

You have confused pins and interrupts I think. Your pinmodes are on pins zero and one. I’ll bet that those are not the interrupt pins on the Teensy. Read the docs for digitalPinToInterrupt.

Did you watch VERY carefully? The LED only stays on for 10 milliseconds (1/100th of a second) each time the pin is connected to Ground. For testing you can use a much longer blink:

    digitalWrite(LEDPin, HIGH);
    delay(300);
    digitalWrite(LEDPin, LOW);

Does the Toon Thermostaat specify a minimum or maximum blink time?

Thx! I will try it tomorrow.
And I made another mistake, it is 1000 imp/kwh. Not per minute.

The toon thermostaat does support 1000 imp/kwh but also 2000 imp/kwh and 10000 imp/kwh.

That’s OK. The code you pointed to in Reply 6 had the right data: 1 pulse per watt-hour (1000 per kWh).

Yesterday I bought an Uno R3. :slight_smile:

I uploaded this code:

//Number of pulses, used to measure energy.
volatile byte pulseCount = 0;

const byte Meter1Pin = 2; // External Interrupt Pin
const byte Meter2Pin = 3; // External Interrupt Pin
const byte LEDPin = LED_BUILTIN;

void onPulse()
{
  pulseCount++;
}

void setup()
{
  pinMode (Meter1Pin , INPUT_PULLUP);
  pinMode (Meter2Pin , INPUT_PULLUP);
  // KWH interrupts attached to external interrupts
  attachInterrupt(digitalPinToInterrupt(Meter1Pin), onPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(Meter2Pin), onPulse, FALLING);
}

void loop()
{
  bool pulse = false;

  noInterrupts();
  if (pulseCount > 0)
  {
    pulse = true;
    pulseCount--;
  }
  interrupts();

  if (pulse)
  {
    // LED pulse rate is limited to 50 pulses per second, max. 
    // = 50 Wh per second
    // = 3000 Wh per minute
    // = 180 kWh per hour
    // = 180 kW
    // = over 800 Amps at 220 Volts, 1600 Amps at 110 Volts
   // Should be fast enough for any home system
    digitalWrite(LEDPin, HIGH);
    delay(300);
    digitalWrite(LEDPin, LOW);
    delay(300);
  }
}

The led is burning. Connecting pin 2 or 3 to ground does nothing.
The blink code to test an arduino is working.

We are going forward!

I changed the code a bit and now it is working.

const byte LEDPin = 13;
pinMode(LEDPin, OUTPUT);
And removed some spaces at pinMode(Meter1Pin, INPUT_PULLUP);

The led is now off. When you connect pin 2 or 3 quickly to ground the led flashes. If you connect it a bit longer the led continues flashing for a few seconds. This is good.
If you connect a S0 interface of a power meter it works great!

Final Code: Special thanks to Johnwasser

//Number of pulses, used to measure energy.
//Made by Johnwasser
volatile byte pulseCount = 0;

const byte Meter1Pin = 2; // External Interrupt Pin
const byte Meter2Pin = 3; // External Interrupt Pin
const byte LEDPin = 13;

void onPulse()
{
  pulseCount++;
}

void setup()
{
  pinMode(Meter1Pin, INPUT_PULLUP);
  pinMode(Meter2Pin, INPUT_PULLUP);
  pinMode(LEDPin, OUTPUT);
  // KWH interrupts attached to external interrupts
  attachInterrupt(digitalPinToInterrupt(Meter1Pin), onPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(Meter2Pin), onPulse, FALLING);
}

void loop()
{
  bool pulse = false;

  noInterrupts();
  if (pulseCount > 0)
  {
    pulse = true;
    pulseCount--;
  }
  interrupts();

  if (pulse)
  {
    // LED pulse rate is limited to 50 pulses per second, max. 
    // = 50 Wh per second
    // = 3000 Wh per minute
    // = 180 kWh per hour
    // = 180 kW
    // = over 800 Amps at 220 Volts, 1600 Amps at 110 Volts
   // Should be fast enough for any home system
    digitalWrite(LEDPin, HIGH);
    delay(60);
    digitalWrite(LEDPin, LOW);
    delay(60);
  }
}

With a Power meter connected it is working prefectly!
Video:

The code works also on a Arduino Nano V3.
I made (remixed) an enclosure for it: Arduino Nano V3 Enclosure with led hole by Jhead - Thingiverse

The script works nice. But there is still one issue.
The pulses are not in a stable ritm.

If a power meter does 1000W the led is flashing in stable pattern. Every 0.x seconds there is a flash. The arduino is not in a stable pattern. It will do 1000 flashes, but not in a stable ritm.
Is there a way to fix this?

Why does it matter it the pulse pattern isn't stable?

If you want to make it so, it's possible, but it may lag a bit at startup I think.

You can use millis in the usual blink without delay way to check pulsecount periodically. If there has been a pulse, send one and decrement pulsecount. This will give a stable stream of pulses.

Independently of that, count how many pulses you get in some time period - a minute perhaps. Use that count to calculate how frequently you should be sending a pulse in "stable" mode. Given that, adjust how long the blink without delay stuff should wait between checking for a pulse.

When you make that adjustment, you may want to avoid doing it all in one go so you get a smooth transition, but as mentioned this will cause a lag while you get to the right rate.

Also, when it's dark and you get no pulses at all, be careful that you don't make the period a ridiculously long length by repeated adjustment.

Hi Wildbill,

The reason why I would like to make the pulse pattern more stable is because I see very high peaks in the graph. They ar much higher then what is possible with my solar pannels.

Do you have any idea what kind of script I need?

This is what I had in mind:

//Number of pulses, used to measure energy.
//Made by Johnwasser
volatile unsigned int pulseCount = 0;
volatile unsigned long LongPulseCount = 0;

const byte Meter1Pin = 2; // External Interrupt Pin
const byte Meter2Pin = 3; // External Interrupt Pin
const byte LEDPin = 13;

unsigned long LastPulseTime;
unsigned long CurrentPulsePeriod = 120;  // Milliseconds
unsigned long PulseCheckedTime;
unsigned long PulseCheckPeriod=60000UL;  // Milliseconds

void onPulse()
{
  pulseCount++;
  LongPulseCount++;
}

void setup()
{
  pinMode(Meter1Pin, INPUT_PULLUP);
  pinMode(Meter2Pin, INPUT_PULLUP);
  pinMode(LEDPin, OUTPUT);
  // KWH interrupts attached to external interrupts
  attachInterrupt(digitalPinToInterrupt(Meter1Pin), onPulse, FALLING);
  attachInterrupt(digitalPinToInterrupt(Meter2Pin), onPulse, FALLING);
}

void loop()
{
  bool pulse = false;
  if (millis() - LastPulseTime > CurrentPulsePeriod)
  {
    noInterrupts();
    if (pulseCount > 0)
    {
      pulse = true;
      pulseCount--;
    }
    interrupts();
    LastPulseTime = millis();
  }
  if (pulse)
  {
    SendPulse();
  }
  CheckPulsePeriod();
}

void   SendPulse()
{
  // LED pulse rate is limited to 50 pulses per second, max.
  // = 50 Wh per second
  // = 3000 Wh per minute
  // = 180 kWh per hour
  // = 180 kW
  // = over 800 Amps at 220 Volts, 1600 Amps at 110 Volts
  // Should be fast enough for any home system
  digitalWrite(LEDPin, HIGH);
  delay(60);
  digitalWrite(LEDPin, LOW);
  delay(60);
}

void CheckPulsePeriod()
{
unsigned long Pulses;
if(millis()-PulseCheckedTime > PulseCheckPeriod)
  {
  noInterrupts();
  Pulses=LongPulseCount;
  LongPulseCount=0;
  interrupts();
  if (Pulses > 0)
    {
    CurrentPulsePeriod = PulseCheckPeriod / Pulses; 
    }
  PulseCheckedTime=millis();  
  }
}

It compiles, but I didn't test it.

It only checks for pulses periodically, so it will emit them steadily. Once a minute it checks to see how many pulses came in and adjusts the outgoing pulse interval accordingly.

I suspect it'll need a bit of tweaking because it will probably sometimes have a pulse that falls in the next slot and it will appear that there was no production there and double in the next. Try it and see.

Hi Wildbill,

Thanks for the help.
There is one problem. The smart thermostat does not like a delay of one minute.
The thermostat is also reading the power usage of the whole house. (I have a smart power meter with a P1 output connected to the thermostat.) When the delay is to big the thermostat is making a mess of it. Is it possible to do it in a very short period? It needs to be in sync with the p1 smart power meter.

Try tweaking the PulseCheckPeriod.

I changed it to 10 seconds. The output is more stable, but not good enough.
The output is sometimes 1800W and 10 seconds later it is 2500W. That is not right, the sky is blue and the sun is shining. I will test 5 seconds or less.

Ok, 1 second is very unstable. Between 1800W and 5000W.
I will try a longer period. 20 seconds.

Edit: 20 seconds is beter. The output is between 2000 and 2400 watt.
30 seconds looks promising. It is between 1900 and 2100. (The sun is going down).