Enable push button pin for a short pule, disable for 2 seconds

I'm trying to use a photocell to detect when somebody reaches for a prank gift box. When shadow covers the photocell it activates a solenoid which pops up the lid of the box to scare the recipient.

So I want the solenoid to get a short pulse, just enough to pop up the lid. Then I want to disable the photocell pin (pin 2) for two seconds to prevent the solenoid from chattering due to quick shadows coming and going.

I have been reading forums and experimenting for about 5 hours and guess it's time to ask for help at this point...

I found several discussions but just can't get it. Help would be so appreciated!

I found enough delay info to allow a shadow to activate the solenoid for a short period (100). But I cannot figure out how to disable the photocell pin for 2 seconds.

(I'm using a push button on pin 2 in place of the photocell and the led on pin 13 in place of the solenoid for testing)

void setup()
{
  pinMode (13, OUTPUT);
  pinMode (2, INPUT);
}

unsigned long lastLowOnPin2;
int pin2state;

void loop()
{
  pin2state = digitalRead(2);

  // record the last time pin 2 was low
  if (pin2state == LOW)
  {
    lastLowOnPin2 = millis();
  }

  if (millis() - lastLowOnPin2 >= 100)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, pin2state);
  }
}

Thanks Delta_G! I'm trying but can't get it to compile to test my new code. I'm pretty sure I don't have the correct quantity of brackets but can't figure them out. (error: 'else' without a previous 'if')

How close am I to the solution? And is there a way to know how many brackets you have and which ones belong to who (whom?)?

void setup()
{
 Serial.begin(9600);
 pinMode (13, OUTPUT);
 pinMode (2, INPUT);
}

unsigned long lastLowOnPin2;
unsigned long popTheTop;
int pin2state;

void loop()
{
 if (millis() - popTheTop >= 2000)
 {
   pin2state = digitalRead(2);

   // record the last time pin 2 was low
   if (pin2state == LOW)
   {
     lastLowOnPin2 = millis();
   }

   if (millis() - lastLowOnPin2 >= 100)
   {
     digitalWrite(13, LOW);
   }
 }
 else
 {
   digitalWrite(13, pin2state);
   popTheTop = millis();

 }

 else
 {
   digitalWrite(13, LOW);
 }
}

Would using a debounce work? set it for 2000milliseconds?

Rossm812 - I'll look into that. -- More confusing code (for me) sigh...

Delta_G - Thanks, I was hoping for a better way to see stuff related to specific 'if' groupings -- like a way to highlight all the lines related to one.

And I knew I should not have asked two questions in one message :slight_smile: What I was really hoping for from you is, did I change the code in the way that you were thinking to ignore Pin 2?

Thanks for going into detail on that.

Now I just have to figure out the 'ignore' code you suggested as I've had no luck with it so far...

It never pops. (Pin 13 never goes high)

Here's my latest code with a little bit of debug info. I hope you can tell me where I'm going wrong...

void setup()
{
  Serial.begin(9600);
  pinMode (13, OUTPUT);
  pinMode (2, INPUT);
}

unsigned long lastLowOnPin2;
unsigned long popTheTop;
int pin2state;

void loop()
{
  if (millis() - popTheTop >= 2000)
  {
    pin2state = digitalRead(2);
    Serial.print("First pin2state ");  
    Serial.println(pin2state);       // debug - when I push the button, this prints a '1' continually 
                                           // after the 100 delay, as long as button is pressed. 
                                           // But Pin 13 led never lights up.
                                           

    // record the last time pin 2 was low
    if (pin2state == LOW)
    {
      lastLowOnPin2 = millis();

    }

    if (millis() - lastLowOnPin2 >= 100)
    {
      digitalWrite(13, LOW);
    }

    else
    {
      digitalWrite(13, pin2state);
      popTheTop = millis();
      Serial.print("pin2state ");
      Serial.println(pin2state);
    }
  }
  else
  {
    digitalWrite(13, LOW);
  }
}

I abandoned the stuff above and started from scratch. In case you're interested, here's code that I think is going to work. Thanks for your input.

int photoCellSensor = 2;     // motion sensor inputs to pin 2
int motorControl_1 = 13;  // output of pin 10 to motor 1
int lastphotoCellState = 0;
int photoCellCounter = 0;
int delayTime = 220;


void setup() {
  pinMode(photoCellSensor, INPUT);
  pinMode(motorControl_1, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int photoCellState = digitalRead(photoCellSensor);  // read motion sensor state
  if (photoCellState != lastphotoCellState)
  {
    if (photoCellState == HIGH)    // if someone stepped in front of photocell it goes high
    {
      photoCellCounter = 0;
      {
        for (int a = 1; a < 2; a++)            // cycle the motors 5 times
        {
          digitalWrite(motorControl_1, HIGH);   //activate the motors briefly
          delay(delayTime);
          digitalWrite(motorControl_1, LOW);
          delay(delayTime);
        }
        delay(2000);
      }
    }
  } else
    // save the current state as the last state,
    //for next time through the loop
    lastphotoCellState = photoCellState;
}

Maybe I'm being thick*, but is that lastphotoCellState = photoCellState; in the right place?

You'll only get to the "else" if they're the same, so no point in setting the old one to be the current one.

Makes more sense to me to do that in the upper part of the "if", which is where they differ, so that next time round the old one is the new current one.

*very likely on a Sunday morning.

edit: that said your braces look a bit funny, so maybe you mean the lastphotoCellState = photoCellState; line to be outside of any control in loop() itself, which makes sense and is the way it's done in the StateChangeDetection example.

Yeah, something is still wrong with it that I didn't notice yesterday -- must be something about Sunday :slight_smile:

It blinks if I hold down the button, where my intention would be to have it activate only once for each button-press.

I'm disappointed that I see so many people getting specific code solutions after struggling far less than I have, and although I got some ideas on what to look for, I got no specific help.

But I'm tired -- after at least a dozen hours of reading and experimenting on what I'm sure would be simple for someone who knows this stuff better than I do, I give up. It works as well as I need it to. Maybe I'll make improvements in a few months when I get smarter.