Go Down

Topic: If value is higher than for given time (Read 864 times) previous topic - next topic

wildbill

Adding
Code: [Select]
Serial.println(currentMillis);
is a code change?
Yes, it is. It probably won't make any difference - probably. Anyone who has spent much time answering questions here has seen the classic situation of the OP making an unmentioned change that they thought irrelevant which actually broke their program. It means that if you're making changes and not posting the revised sketch, the people who might have helped you will shrug & move on.

Robin2

#16
May 14, 2017, 03:09 pm Last Edit: May 14, 2017, 03:10 pm by Robin2
And no
Code: [Select]
Irms < 0.03
is not in the code because as i wrote it does not work.
If you believe it does not work then you must have had a version of the code that included it.

One of the important lessons about debugging is that the cases that don't work are often very useful indicators of the problem - don't discard them without carefully studying them.  So post the code that includes that change.


Plus what @wildbill said.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MrGlasspoole

Ok, step by step (ooh baby  :) )

This one turns on the relay after 3 seconds if load is detected but does not turn off the relay after removing the load:
Code: [Select]
#include <EmonLib.h>   // Get it here: github.com/openenergymonitor/EmonLib

/**************************************************************
* MISC SETUP                                                  *
**************************************************************/
#define DEBUG 1                      // Set to 1 for serial port output
const uint32_t SERIAL_BAUD = 9600;   // Set serial 0 speed
EnergyMonitor checkPower;            // Create an instance

const uint8_t RELAY = 8;   // Relay circuit is connected to D8
const uint8_t SENSOR = A3; // ECS1030-L72 is connected to A3

// Define switch pins
const uint8_t pinS[] = {3, 4};                      // Array of used switch pins
uint8_t pinSCount = sizeof(pinS) / sizeof(pinS[0]); // Count used switch pins

// Define unused pins
const uint8_t pin[] = {2, 5, 6, 7, 9, 10, 11, 12, 13}; // Array of unused digital pins
const uint8_t pinA[] = {A0, A1, A2, A4, A5, A6, A7};   // Array of unused analog pins
uint8_t pinCount = sizeof(pin) / sizeof(pin[0]);       // Count unused digital pins
uint8_t pinACount = sizeof(pinA) / sizeof(pinA[0]);    // Count unused analog pins

/**************************************************************
* SETUP                                                       *
**************************************************************/
void setup() {

  #ifdef DEBUG
    Serial.begin(SERIAL_BAUD); // Initialize serial communications
    while (!Serial) {;}        // Wait for serial port to connect
  #endif // END DEBUG
 
  for (uint8_t i = 0; i < pinCount; i++) {
    pinMode(pin[i], OUTPUT);    // Set unused digital pins as output
    digitalWrite(pin[i], LOW);  // Set unused digital pins state to low
  }

  for (uint8_t i = 0; i < pinACount; i++) {
    pinMode(pinA[i], OUTPUT);    // Set unused analog pins as output
    digitalWrite(pinA[i], LOW);  // Set unused analog pins state to low
  }

  for (uint8_t i = 0; i < pinSCount; i++) {
    pinMode(pinS[i], INPUT_PULLUP);  // Set switch pins as input and enable internal pull-up resistor
  }

  pinMode(RELAY, OUTPUT);     // Set Relay pin (D8) as output
  digitalWrite(RELAY, LOW);   // Set Relay to off

  checkPower.current(SENSOR, 20);  // Sensor input pin (A3) and calibration

}

/**************************************************************
* AUTOMATIC LOOP                                              *
**************************************************************/
unsigned long noLoadTime = 0;
unsigned long loadRemoved = 0;
unsigned long turnOnDelay = 3000;
unsigned long turnOffDelay = 3000;
bool loadState = false;

void automatic() {

  double Irms = checkPower.calcIrms(1480);   // Calculate Irms only
  unsigned long currentMillis = millis();

  if (loadState == false) { // There is no load
       
    if(Irms < 0.03) {
      noLoadTime = currentMillis;
    }

    if (millis() - noLoadTime >= turnOnDelay) {  // If RMS is higher then 0.03A longer then 3 seconds
      digitalWrite(RELAY, HIGH);                 // turn relay on
      loadState = true;
    }

  }

  if (loadState == true) { // There is load
 
    if(Irms > 0.03) {
      loadRemoved = currentMillis;
    }

    if ((millis() - loadRemoved) >= turnOffDelay) {
      digitalWrite(RELAY, LOW);
      loadState = false;
    }
   
  }

  #ifdef DEBUG
    Serial.print(Irms*230.0);  // Apparent power
    Serial.print(" ");
    Serial.println(Irms);      // Irms
    Serial.println(currentMillis);
  #endif // END DEBUG

}

/**************************************************************
* MAIN LOOP                                                   *
**************************************************************/
void loop() {
 
  uint8_t switchState_1 = digitalRead(3);  // Read the switch value (pin D3)
  uint8_t switchState_2 = digitalRead(4);  // Read the switch value (pin D4)
 
  if(switchState_1 == LOW) {           // If pin 3 is low
    digitalWrite(RELAY, HIGH);         // turn relay on
    loadState = false;                 // and reset load detection state
  } else if (switchState_2 == LOW) {   // If pin 4 is low
    loadState = false;                 // reset load detection state
    automatic();                       // and run the automatic loop
  } else {
    digitalWrite(RELAY, LOW);          // Turn relay off
    loadState = false;                 // and reset load detection state
  }

  #ifdef DEBUG
    Serial.println(loadState);      // Irms
  #endif // END DEBUG

}

MrGlasspoole

The next one. It was dark and now i did see that the LED (that i use instead of a relay for testing) did flicker weakly.
Code: [Select]
#include <EmonLib.h>   // Get it here: github.com/openenergymonitor/EmonLib

/**************************************************************
* MISC SETUP                                                  *
**************************************************************/
#define DEBUG 1                      // Set to 1 for serial port output
const uint32_t SERIAL_BAUD = 9600;   // Set serial 0 speed
EnergyMonitor checkPower;            // Create an instance

const uint8_t RELAY = 8;   // Relay circuit is connected to D8
const uint8_t SENSOR = A3; // ECS1030-L72 is connected to A3

// Define switch pins
const uint8_t pinS[] = {3, 4};                      // Array of used switch pins
uint8_t pinSCount = sizeof(pinS) / sizeof(pinS[0]); // Count used switch pins

// Define unused pins
const uint8_t pin[] = {2, 5, 6, 7, 9, 10, 11, 12, 13}; // Array of unused digital pins
const uint8_t pinA[] = {A0, A1, A2, A4, A5, A6, A7};   // Array of unused analog pins
uint8_t pinCount = sizeof(pin) / sizeof(pin[0]);       // Count unused digital pins
uint8_t pinACount = sizeof(pinA) / sizeof(pinA[0]);    // Count unused analog pins

/**************************************************************
* SETUP                                                       *
**************************************************************/
void setup() {

  #ifdef DEBUG
    Serial.begin(SERIAL_BAUD); // Initialize serial communications
    while (!Serial) {;}        // Wait for serial port to connect
  #endif // END DEBUG
 
  for (uint8_t i = 0; i < pinCount; i++) {
    pinMode(pin[i], OUTPUT);    // Set unused digital pins as output
    digitalWrite(pin[i], LOW);  // Set unused digital pins state to low
  }

  for (uint8_t i = 0; i < pinACount; i++) {
    pinMode(pinA[i], OUTPUT);    // Set unused analog pins as output
    digitalWrite(pinA[i], LOW);  // Set unused analog pins state to low
  }

  for (uint8_t i = 0; i < pinSCount; i++) {
    pinMode(pinS[i], INPUT_PULLUP);  // Set switch pins as input and enable internal pull-up resistor
  }

  pinMode(RELAY, OUTPUT);     // Set Relay pin (D8) as output
  digitalWrite(RELAY, LOW);   // Set Relay to off

  checkPower.current(SENSOR, 20);  // Sensor input pin (A3) and calibration

}

/**************************************************************
* AUTOMATIC LOOP                                              *
**************************************************************/
unsigned long noLoadTime = 0;
unsigned long loadRemoved = 0;
unsigned long turnOnDelay = 3000;
unsigned long turnOffDelay = 3000;
bool loadState = false;

void automatic() {

  double Irms = checkPower.calcIrms(1480);   // Calculate Irms only
  unsigned long currentMillis = millis();

  if (loadState == false) { // There is no load
       
    if(Irms < 0.03) {
      noLoadTime = currentMillis;
    }

    if (millis() - noLoadTime >= turnOnDelay) {  // If RMS is higher then 0.03A longer then 3 seconds
      digitalWrite(RELAY, HIGH);                 // turn relay on
      loadState = true;
    }

  }

  if (loadState == true) { // There is load
 
    if(Irms < 0.03) {
      loadRemoved = currentMillis;
    }

    if ((millis() - loadRemoved) >= turnOffDelay) {
      digitalWrite(RELAY, LOW);
      loadState = false;
    }
   
  }

  #ifdef DEBUG
    Serial.print(Irms*230.0);  // Apparent power
    Serial.print(" ");
    Serial.println(Irms);      // Irms
    Serial.println(currentMillis);
  #endif // END DEBUG

}

/**************************************************************
* MAIN LOOP                                                   *
**************************************************************/
void loop() {
 
  uint8_t switchState_1 = digitalRead(3);  // Read the switch value (pin D3)
  uint8_t switchState_2 = digitalRead(4);  // Read the switch value (pin D4)
 
  if(switchState_1 == LOW) {           // If pin 3 is low
    digitalWrite(RELAY, HIGH);         // turn relay on
    loadState = false;                 // and reset load detection state
  } else if (switchState_2 == LOW) {   // If pin 4 is low
    loadState = false;                 // reset load detection state
    automatic();                       // and run the automatic loop
  } else {
    digitalWrite(RELAY, LOW);          // Turn relay off
    loadState = false;                 // and reset load detection state
  }

  #ifdef DEBUG
    Serial.println(loadState);      // Irms
  #endif // END DEBUG

}

Only change is < instead of > in
Code: [Select]
  if (loadState == true) { // There is load
 
    if(Irms < 0.03) {

Robin2

Ok, step by step (ooh baby  :) )
I'm sure I'm crap at lots of things but I reckon I am a little better than average at diagnosis. And there is no substitute for baby steps.

Quote
It was dark and now i did see that the LED (that i use instead of a relay for testing) did flicker weakly.
Are you saying that the LED goes on for 3 seconds and then goes off for a very brief interval before going on for another 3 seconds?

Remember I can't see your workbench so you need to provide all the fine detail.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

756E6C

Pins A6 & A7 are analog input ONLY, don't know what effect (if any) pinModing them to OUTPUT will have.

BulldogLowell

Pins A6 & A7 are analog input ONLY, don't know what effect (if any) pinModing them to OUTPUT will have.
just read the specs...

Quote
Pin mapping

The analog pins can be used identically to the digital pins, using the aliases A0 (for analog input 0), A1, etc. For example, the code would look like this to set analog pin 0 to an output, and to set it HIGH:

pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);
Pullup resistors

The analog pins also have pullup resistors, which work identically to pullup resistors on the digital pins. They are enabled by issuing a command such as

digitalWrite(A0, INPUT_PULLUP);  // set pullup on analog pin 0
Be aware however that turning on a pullup will affect the values reported by analogRead().

756E6C

@BulldogLowell:
  So, I can set pin A7 as digital output and blink an LED with it?

BulldogLowell

@BulldogLowell:
  So, I can set pin A7 as digital output and blink an LED with it?
what happened when you tried?

756E6C

I woke up in an alternate universe, it was nice knowing you all.

MrGlasspoole

#25
May 15, 2017, 09:07 pm Last Edit: May 16, 2017, 12:10 am by MrGlasspoole
Are you saying that the LED goes on for 3 seconds and then goes off for a very brief interval before going on for another 3 seconds?
If i use
Code: [Select]
if (loadState == true) { // There is load
 
    if(Irms < 0.03) {

the LED flickers fast. Really fast. But so weak that i can see it only if it's nearly dark in the room.

And i did not think about baby steps - i just had the New Kids on the Block song in my head :)

Robin2

the LED flickers fast. Really fast. But so weak that i can see it only if it's nearly dark in the room.
You have waited just the right amount of time to reply so that the thing has gone completely out of my head. I will bookmark this to look at it more closely this evening or tomorrow when I have more time.

I am still confused by your use of the variable name "loadState" because it does not actually seem to coincide with the state of the load. What does it really represent?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MrGlasspoole

#27
May 16, 2017, 12:11 pm Last Edit: May 16, 2017, 12:11 pm by MrGlasspoole
loadState = if there is load.
If the sensor recognizes there is something (load) connected to the 230v outlet.

I also at the circuit:

Robin2

loadState = if there is load.
If the sensor recognizes there is something (load) connected to the 230v outlet.
I still have not had / do not have time to study your code - but I have not forgotten.

I wonder if circuitActivated might be a more meaningful name than loadState - because it seems that the purpose of your code is to turn off the circuit (de-activate it) if there in no load. I think the line  double Irms = checkPower.calcIrms(1480); is what actually determines if there is a load.

Please correct me if I have misunderstood your system.

IMHO having names for variables that properly describes their roles makes it much easier to spot silly mistakes in logic.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MrGlasspoole

checkPower.calcIrms(1480) is explained at the Emon Library like so:
Quote
The sketch reads approximately 106 samples of current in each cycle of mains at 50 Hz. 1480 samples therefore works out at 14 cycles of mains. That will give you a good average reading.
But since i'm not building a "Kill A Watt" it's not critical how much the sensor is reading.
The circuit just needs to detect if the table saw, router or sander is running to turn on the vac.

And without the on/off delay it works. But i can't figure out how to but that delay in there :(

Go Up