Halloween Prop controller

You can write code to sense when an Light Dependent Resistor (what I assume that you mean by photocell) changes from light to dark or light to dark so that you can initiate an action only when the light changes from one state to the other (detect the transition, not the level). For instance here is a demo that will increase the count only when the light changes from dark to light. The state of the LED on pin 13 will toggle when the light changes from light to dark. The same mechanism is used to detect state changes in switches.
A tutorial on state change.

// analog state change by groundFungus aka c.goulding

const byte sensorPin = A0;
const byte ledPin = 13;

const int threshold = 600;
// hysteresis added to prevent chatter around threshold with 
// slow moving signals
const int hysteresis = 25; 

bool sensorState = true;
bool lastSensorState = true;

int count = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println("analog state change example");
  pinMode(sensorPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  int sensorValue = analogRead(sensorPin);
  if (sensorValue < threshold - hysteresis)
  {
    sensorState = true;
  }
  else if (sensorValue > threshold + hysteresis)
  {
    sensorState = false;
  }

  if (sensorState != lastSensorState)
  {
    if (sensorState == true)
    {
      count++;
      Serial.print("count = ");
      Serial.println(count);
    }
    else
    {
      digitalWrite(ledPin, !digitalRead(ledPin));      
    }

    lastSensorState = sensorState;
  }
}

image
LDR wired to ground. Load resistor is internal pullup.

Hope you find this useful.

Hmm? I entered the coding into the existing sketch and the LED's are doing the same as in the previous version of the sketch. Rather than installing a push button switch, I simply used the little pin wires that came with the arduino kit, one plugged into Pin 3, the other wire into ground. Touched the two wires resembling a switch closed contacts and nothing changed. The LEDs kept blinking per the previous code. Maybe I didn't enter the coding right. For instance, do I enter the "setup" part of the new code above the other inputs in the "Setup" section? Same with the "Loop" section?

A switch needs to be wired properly to work. If using a wire as a switch the input is floating if the wire is disconnected. A floating input's state is indeterminate (random). Use the pinMode(pin, INPUT_PULLUP); funciton to set the pin to a known state when the wire is disconnected (switch open). The pin will read HIGH when the wire is not connected (switch open) and LOW when connected to ground.

I mistakenly called them photo cells. They are actually Photoelectric Sensors with a reflector for max range of 2m. Switch is 200MA. From Amazon. I used a number of these last year for Halloween single action props. I used 5amp rated 12v PS also from Amazon to power the sensor and used automotive 12V relay from sensor to 12VDC solenoid air valve (about 300MA to 400MA). I plan similar setups, but this year I want multiple movements on some new props. With Arduino I can get that and still power multiple solenoid valves via mosfets or 5v relays from the Arduino board. The mechanics and wiring of putting all this together is the easy part. It's the coding of the arduino that has me baffled. UGH!! UGH!!!! But, I'm learning... I think. Oh, I also used PIR's in places where a photoelectic sensor would not work well. Meaning, Photoelectric is on-off as each person passes through the beam. That's good for certain props. Bad for other props. PIR's are good since it would energize a solenoid valve and remain open until the PIR timed out. Seems like with using an arduino, either switch (Photoelec or PIR) will work since the arduino provides the timing after trigger.

All you did wrong was to not post the code here so we can see what you did wrong!

a7

See, which coding into what existing sketch?

Bandwidth is high. Don't worry about posting a complete sketch again and again with but minor changes that you describe at the same time. It is easier for you to do that than for us to read, backfit and test... too many ways for that to go wrong.

a7

Here is the code. Disregard the red squiggly lines under some of the text. I had to copy and paste, and somehow the lines showed up when I pasted. You'll also see that I changed the name of the LED's and added some as I stated earlier. It's easier for me to keep track.

// This is for the Kneeling Zombie

define sensorPin A5

define LED1 6

define LED2 7

define LED3 8

define LED4 9

define LED5 10

void setup()
{

Serial.begin(115200);
Serial.print("\nhello world.\n");

pinMode(sensorPin, INPUT); // may need INPUT_PULLUP mode

pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
pinMode(LED5, OUTPUT);

}

void loop()
{

if (digitalRead(sensorPin))
Serial.println("sensor reporting HIGH");
else
Serial.println("sensor reporting LOW");

delay(2000); // 4 times a second is plenty too much

digitalWrite(LED1, HIGH); // turn on the LED
delay(500);

digitalWrite(LED2, HIGH); // turn on the other LED
delay(500);

digitalWrite(LED3, HIGH); // turn on the other LED
delay(500);

digitalWrite(LED4, HIGH); // turn on the other LED
delay(500);

digitalWrite(LED5, HIGH); // turn on the other LED
delay(500);

digitalWrite(LED1, HIGH); // turn off all LEDs
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
digitalWrite(LED4, HIGH);
digitalWrite(LED5, HIGH);
delay(2000);

digitalWrite(LED5, LOW); // begin turning off all LEDs
delay (1000);

digitalWrite(LED4, LOW);
delay (1000);

digitalWrite(LED3, LOW);
delay (1000);

digitalWrite(LED2, LOW);
delay (1000);

digitalWrite(LED1, LOW);
delay (2000);

}

Huh. The red squiggly lines didn't go through when I posted. Also, the rest of it didn't go through the same. I think I know why it didn't post like it was written. The forum asked when I hit reply if this was a code. I accidentally hit "no". OOPS! Do you want me to resend it properly?

Also, I did initially use pin 3 for the sensor as you had in the code.

define sensorPin 3

When that didn't work, I tried other pins. One was A5 as shown in the code. None of the pins used made any difference.

You can, or since you caught it just right away, edit your post.

Easiest, I find:

Use the IDE Autoformat tool to make your code pretty.

Copy the entire sketch, then come here and use the <CODE/> button in the message composition window toolbar and paste where it says.

But right away I think you need to look at the syntax for the if/else statement.

HTH

a7

Also… if you are just using a wire to connect the pin to ground, you will need INPUT_PULLUP as the pin mode and that will make your switch read HIGH (true) without the wire, and LOW when you connect the pin to ground with the jumper wire.

So next next, get some pushbuttons. :wink:

a7

# define sensorPin  A5
# define LED1  6
# define LED2  7
# define LED3  8
# define LED4  9
# define LED5  10


 
void setup()
{

   Serial.begin(115200);
  Serial.print("\nhello world.\n");

  pinMode(sensorPin, INPUT);  // may need INPUT_PULLUP mode

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);

 
}

void loop()
{

   if (digitalRead(sensorPin))
    Serial.println("sensor reporting HIGH");
  else
    Serial.println("sensor reporting LOW");

  delay(2000); // 4 times a second is plenty too much

  digitalWrite(LED1, HIGH);       // turn on the LED
  delay(500);

  digitalWrite(LED2, HIGH);  // turn on the other LED
  delay(500);

  digitalWrite(LED3, HIGH);  // turn on the other LED
  delay(500);

  digitalWrite(LED4, HIGH);  // turn on the other LED
  delay(500);

  digitalWrite(LED5, HIGH);  // turn on the other LED
  delay(500);

  digitalWrite(LED1, HIGH);        // turn off all LEDs
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, HIGH);
  delay(2000);

  digitalWrite(LED5, LOW);      // begin turning off all LEDs
  delay (1000);

  digitalWrite(LED4, LOW);
  delay (1000);

  digitalWrite(LED3, LOW);
  delay (1000);

  digitalWrite(LED2, LOW);
  delay (1000);

  digitalWrite(LED1, LOW);
  delay (2000);

 
}

Just realized there are 5 push buttons in the Arduino kit.

I read that "If Statement" document this morning and re-read it again just now. Makes some sense, but where the user needs to enter the "somecondition" part, I can define that, but doesn't that need to be in a very specific language? Like in the example below, it shows "AnalogValue". I suppose that's defined in "const int" as "AnalogPin = A0". Does it need to be very specific or can I name it anything I want as long as I show the same in the loop portion?

// These constants won't change:
const int analogPin = A0;   // pin that the sensor is attached to
const int ledPin = 13;      // pin that the LED is attached to
const int threshold = 400;  // an arbitrary threshold level that's in the range of the analog input

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communications:
  Serial.begin(9600);
}

void loop() {
  // read the value of the potentiometer:
  int analogValue = analogRead(analogPin);

  // if the analog value is high enough, turn on the LED:
  if (analogValue > threshold) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }

I found INPUT_PULLUP on an Arduino programming cheat sheet, but scratching my head on this. Need to figure out how to apply it. One way or another I'm going to figure this out!!

Use INPUT_PULLUP as the mode in pinMode() and the internal pullup resistors are activated keeping the pin HIGH unless explicitly taken LOW. Wire a button to take the pin LOW when the button is pressed and the pin will always be at a known state. Detect the LOW state to test whether the button is currently pressed

The link to the term "floating" in post #23 has an explanation of INPUT_PULLUP.

I mean this in the kindest possible way, but I am not going to spend too much time being kind.

I doubt seriously if the othe major things you've learned, like getting a degree in Mechanical Engineering, was done in the manner you have adopted at the moment here.

Programming is a big deal. People spend years and many still find occasions for learning new stuff.

You will not get very far if you spoon eat your way to any competence at all, and you will wear the patience of those feeding you.

Take one hour, spend seven minutes each looking over eight tutorials or websites or whatever turns up when you google

  Arduino  programming basics

or

  C language tutorial

or variations.

There is no one perfect website or book or whatever what fits everyone's level,of knowledge, intelligence and learning style.

Find a website that looks like a good match, perhaps you like the Ice Tea guy, who you will def turn up if your searches are good. I don't. I like the breezy young chick woman who looks like she makes some of the slog fun.

Maybe you are a reader. I find videos to be intolerable - I would much rather read than sit and watch. Life is too short for a 27 minute video that you might get the nuggets it contains from reading one page elsewhere.

But the point is for awhile, you are going to have to just put in the time and summon up the motivation to keep looking for answers. Coming here about this or that little stumbling block each time one comes along will be slow and painful progress to what will inevitably be an unsatisfactory "mastery" of basic concepts of programming, and the particular fun we have here down near where it really happens talking to relays and sensors and motors and stuff like that.

Google for projects you know must exist, and read the blog-type exposure proud authors are prone to publish. Some code is better than others, some sites are routinely slammed for reasons, I won't mention any by name cough! instructables, but every sketch you read, and every schematic you see will tell you something and inform your inquiries.

And by read, I do mean read. Read read read the code, follow along threads on these fora that look like the kind of thing you aspire to do. Right now there are several threads that are similar to yours where ppl are getting into the same jams, asking similar questions and getting, variously, the attention of we who hang out here hoping to help and inspire.

There is no good writer of anything written who is not also widely read.

Don't worry about feeling dumb or coming here when you've seen conflicting or confusing things elsewhere. Did I say no one was born knowing any of this, and we all struggle from time to time with something not going the way it should. Just now, for example, I am reading some code that @alto777 wrote a few years ago and I am thinking what was this guy smoking, and why why why did he do this thing here, so confusing and not a damn comment in sight. If I was a violent person I'd hunt him down and give him a good dope-slap for the mess he left for me to come across one day.

This all I wrote for you, but anyone reading along may benefit from the same advices.

HTH

a7

2 Likes

LOL!!! Nope, I don't take offense to any of this. A little more of my background. I played college and two years of pro football... linebacker. Took many vicious beatings, LOL! So, you know I must be a bit warped. Then got my engineering degree. It takes a lot to get me pissed off. Plus, I know it's best to learn the hard way. I will take your advice and try to figure out more of what more is needed. The bottom line is you have given me a great start. The code you provided is doing what I want and I can change the timing as I think will fit the prop. If I can just figure out how to start the sequence with a PIR, and stop it until the PIR is activated again, I win. And so do the people who come to the Halloween "Wicked Woods"!! Thanks!!

Well, I feel like I am running out of time because I need to start building the Wicked Woods and Haunted Maze. A whole lot to do. Needs to be up and all props (about 15 total) tested by mid Oct. I have been beating my head against a wall to figure out the "if" function and have tried to understand, but not quite getting it. Probably over thinking it. So, put it aside and it may come to me later.

Since I'm concerned about time, I came up with a work around solution. Not ideal, but tested and it works. Since the timing of the LEDs works as I want, but can't start / stop through the arduino, I will simply let a PIR control the on/off of the arduino. I have some PIRs that are adjustable from 1 minute to 10 minutes. I will adjust to 1 minute from actuation. Tried it today and it works great. Even wired in a relay and solenoid air valve and that works. I may replace the relay with mosfet when I go to build the whole unit. At this point, it's an effective work around. We did a lot of work arounds at the Nuclear Power Plant I used to work at. I probably shouldn't have said that!!!

Anyway, when I have more time, I will keep studying to see if I can get the code right. Many thanks for your help!

Please read the sketch below line by line. See if it fits in with what you have discovered about the if/else statement.

Wire a pushbutton between pin 3 on the UNO and ground. Run the code. Marvel. See if you can figure out how long you might have to press the button to see a reaction.

Open the serial monitor window and make sure the band rate is set to match, 115200.

# define sensorPin  3

void setup()
{
  Serial.begin(115200);

  pinMode(sensorPin, INPUT_PULLUP);
}

void loop()
{
  if (!digitalRead(sensorPin)) {
    Serial.println("               you pressed or are still pressing the button.");
    Serial.println("               I am going away for ten seconds");
    delay(10000);
    Serial.println("");
  }
  else {
    Serial.println("all quiet in Entrevias!");
  }

  delay(250); // 4 times a second is plenty too much
}

No, no you should not have.

Good Luck.

a7