Help with if statement override

So I am making a cat feeder attached to a scale. The feeder has a lid on it driven by a servro.
We have two cats, a skinny one and a fat one. I'm trying to make it so the lid only opens for the skinny one.

There's about 5 lbs difference between them. I got a version working but the lid was freaking out the cat because it flutters as she's walking on. So what I want it to do is open as soon as something is on it between 7 and 10 lbs. And then it wont close again for 60 second once it isn't in that range as not to scare the cat until she's done eating. (in the code I have it to ten seconds for testing purposes)

The exception is that I want it to close immediately if the weight goes over 12lbs. Because if the fat cat gets on the scale and is half on it enough to just hit 7-10lbs for a second, then the lid is open for a a minute which is plenty of time for him to eat.

I think that would give enough leniency for the fluctuation of walking onto the scale but I can't get it working. If I just have the if and the else statement it seems to work fine. It's when I add in the second if condition in it seems that the delay part doesn't work.

I'm using this millis method because a delay just seems to block everything but I'm not sure if I'm using it correctly. So is there a different way to do if statements for arduino, or is it my delay part of the script? I've tried a few different set ups, but no luck. Like this example sorta works, but it's never a consistent 10 second delay, if there's any delay at all.

/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <Servo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  4
#define CLK  3

HX711 scale(DOUT, CLK);
Servo lidservo; //decalre the servo is "lidservo"
 float average; //decalare floating point variable "average"
 long previousTime = 0;
 long interval = 10000;

void setup() {
  Serial.begin(9600);
  Serial.println("measuring cat weight");
  lidservo.attach (6);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare();	//Assuming there is no weight on the scale at start up, reset the scale to 0


  Serial.println("Readings:");
}

void loop() {
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"
    Serial.println(average);
  unsigned long currentTime = millis();


   if(average > 12.5)
    {
    lidservo.writeMicroseconds (750);
    } 

    else
    {
       if ( average > 7 && average < 10)
        {
        lidservo.writeMicroseconds (1690);
        }

       else
        {
        if(currentTime - previousTime > interval)
          {
          previousTime = currentTime;
          lidservo.writeMicroseconds (750);
          }
        } 
     }
}

This is your timestamp handler:

      if(currentTime - previousTime > interval)
          {
          previousTime = currentTime;

It is nested inside 3 if statements, so chances are it's not being performed very often. Didn't you want to have regular time intervals? Not sure, because I don't know the overall intent of that section of code.

One more thing. Your time variables must be unsigned long, not just long.

It doesn't need to be nested. Just whatever works.

Essentially I want something that works like

if the weight is between 7 and 10 lbs open the lid

if the weight is over 12 lbs, close the lid immediately because fatty is eating the food.

else, wait a minute and close the lid as not to freak out the cat. But don't forget, if fatty steps on the scale within that minute, close it immediately. Also, if we suddenly get back to 7-10 lbs within that minute, forget this part and go back to if statement 1. Just don't shut suddenly if they right cat is on here because it freaks here out.

Which is essentially what I tried to start with but I wasn't seeing the delay. I had something like:

 if ( average > 7 && average < 10)
    {
    lidservo.writeMicroseconds (1690);
    }

if(average > 12.5)
    {
    lidservo.writeMicroseconds (750);
    } 

else
    {
     if(currentTime - previousTime > interval)
          {
          previousTime = currentTime;
          lidservo.writeMicroseconds (750);
          }
     }

Ah, but that was it. The tutorial I followed didn't have unsigned and const on the first two variables. I added those and now it works.

Thanks!

So there's a new issue now. I'm not sure if I should start a new thread or continue here.

So it works, but the lid arm will randomly close and open real quick, like a slap, randomly when the cat is sitting on the scale. Around every 30ish seconds it seems like.
It also closes far sooner than 60 seconds after the cat gets off the scale.

Luckily I'm just training her to get used to the servo right now so it's not hitting her. But does anybody have any idea what's going on? I'm guessing maybe a random fluctuation in the scale? She's hardly moving when it happens. Would more samples and then average those samples be a good bet kinda thing?

The scale seemed fairly accurate when I tested it.

Please post the full code that you are using.

technicallyartistic:
So there's a new issue now. I'm not sure if I should start a new thread or continue here.

Definitely continue here.

As @UKHeliBob says, please post your latest code.

Likely reasons are either that your logic is hunting between two values (eg > 12 and < 12) and if so you need to introduce hysteresis (eg > 12 and < 11.5). Or you should simply have a time interval after the lid closes before it can open again.

...R

Be sure you record this for YouTube - you are about to discover just how cunning a fat cat can be when there's food involved.

PaulMurrayCbr:
just how cunning a fat cat can be

It's not for nothing that Merchant Bankers and such are called "fat cats"

...R

Sorry. I forgot to add that last post. Meant to.

I was trying to read up on hysteresis before, but didn't fully understand what it was.

/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND
 
 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.
 
*/

#include "HX711.h"
#include <Servo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  4
#define CLK  3

HX711 scale(DOUT, CLK);
Servo lidservo; //decalre the servo is "lidservo"
 float average; //decalare floating point variable "average"
 unsigned long previousTime = 0;
 const long interval = 60000;

void setup() {
  Serial.begin(9600);
  Serial.println("measuring cat weight");
  lidservo.attach (6);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare();	//Assuming there is no weight on the scale at start up, reset the scale to 0


  Serial.println("Readings:");
}

void loop() {
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"
    Serial.println(average);
  unsigned long currentTime = millis();



    if ( average > 7 && average < 10)
       {
       lidservo.writeMicroseconds (1690);
       }

       
    if(average > 12.5)
       {
       lidservo.writeMicroseconds (750);
       } 

    else
       {
       if(currentTime - previousTime > interval)
          {
          previousTime = currentTime;
          lidservo.writeMicroseconds (750);
          }
      } 
}

I would have thought the logic would look more like this

/*

 Arduino pin 2 -> HX711 CLK
 3 -> DAT
 5V -> VCC
 GND -> GND

 The HX711 board can be powered from 2.7V to 5V so the Arduino 5V power should be fine.

*/

#include "HX711.h"
#include <Servo.h>

#define calibration_factor -12350.0 //This value is obtained using the SparkFun_HX711_Calibration sketch

#define DOUT  4
#define CLK  3

HX711 scale(DOUT, CLK);
Servo lidservo; //decalre the servo is "lidservo"
float average; //decalare floating point variable "average"
unsigned long previousTime = 0;
const long interval = 60000;

void setup() {
  Serial.begin(9600);
  Serial.println("measuring cat weight");
  lidservo.attach (6);

  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare();	//Assuming there is no weight on the scale at start up, reset the scale to 0


  Serial.println("Readings:");
}

void loop() {
  average = (scale.get_units(10)); //Gets units from scale and stores in the variable "average"
  Serial.println(average);
  unsigned long currentTime = millis();

  if (average <= 7 && currentTime - previousTime > interval)
  { //no cat on scale wait for timer to finnish
    previousTime = currentTime;//one time reset timer
    lidservo.writeMicroseconds (750);//close lid
  }

  //may require extra code as the above line will
  //execute every time the timer is done. might have to add a flag
  // to indicate lid is already closed?

  if ( average > 7 && average < 10)
  {
    lidservo.writeMicroseconds (1690);
    previousTime = currentTime;//small cat on scale stop timer
    //timer stays stopped until cat leaves scale
  }

  if (average > 12.5)
  { //fat cat on scale shut lid
    lidservo.writeMicroseconds (750);
  }
}

technicallyartistic:
I was trying to read up on hysteresis

Glad to see you figured out my lousy spelling. Sorry.

...R