Tuesday, November 8, 2016

Arduino for dummies (Halloween monster project)-updated...Finished!

OK, project finished...video is first...after that original article on the project.  Worked great, scared kids...but everyone loved it!






---------------Original Article------------------------------------------------------

Ok, this is not a class on how to Arduino...this is a dummy (me) using an Arduino.

For the record...I am not uneducated about computers and programming...however, I know nothing about the Arduino...

I do know a bit about circuits.  I did learn Basic, Pascal, and Fortran77 in college.   I haven't programmed anything more complex than an Excel table lookup since college.  (and if you know how long it has been since colleges taught Fortran77...)  (The computer lab we had used one of these... Burroughs B6700)

I was always curious about the Arduino and the other small computers...but you have to have a need before you can motivate yourself to learn...well me anyway.

Good links

Circuits.io
arduino.cc
diyhacking.com
adafruit.com

Here was the 'need'.  We have a couple of 6' tall animatronic monster Halloween decorations.  They have some built in sounds and movements.   They can be triggered by a noise, or a button on the base.



It takes a sharp clap sound to activate the noise trigger...but I wanted something more controllable...and more automated.  For a few years I simply had about 20' of wire from the monster tapped into the switch in the base, and the other end was bare wires...I couldn't be bothered to solder a button in (5 year proof of concept test...)

I finally decided that I wanted the monster to be motion activated, as well as having the button trigger if necessary.   The problem with the button trigger is if you trigger it while it is doing its thing, the event will stop.   Some events are only 15 sec long or so, but one is 65 seconds (It sings and dances to Monster Mash)...I don't want to accidentally cut out the event.

So here is where the Arduino comes in.  I was sure I could create some trigger inputs, a relay output, and a self timer.




Here is the display when triggered.





Here is the display when timer is done.





Here is the circuit as viewed on circuits.io   The resistors connected to the LCD and the LED are 220ohm   The one connected to the pushbutton is a 10k, the potentiometer is 10k.  I put 9v into the Arduino and use the 5v from the Arduino.  The PIR (infrared motion detector) that I bought from Adafruit has a different pinout...but the Data goes to pin 6 and the other two pins are power.





And here is the code in all its glory...if you paste this into circuits.io, and wire up the circuit as shown, it will work.  (note, the upper left power leads come from a 9V battery...on the actual Arduino I have it plugged into the power jack)   (could the code be written better...duh) (oh, and this code works, but there are some edits I have since made to make the display look better...)  (BTW the screenshot of the circuit shows an additional switch to continuously activate the trigger...If I implement this in the hardware, then at the end of the timer, it will automatically start again.)


// include the library code
#include

// initalize the library with the numbers of the interface pins
LiquidCrystal lcd(12,11,5,4,3,2);

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int relay = 8;
int button = 7; // switch is on pin2
int buttonValue = 0; //switch defaults to 0 or LOW
int inputPin = 6;   // choose the input pin (for PIR sensor)
int pirState = LOW;  // we start, assuming no motion detecte
int val = 0;         // variable for reading the pin status
  
int runTimer = 1;
int runFor = 3; // time in seconds
int data = 0;

// the setup routine runs once when you press reset:
void setup() {
  // set up the LCDs colums and rows
  lcd.begin(16,2);
  //print message to LCD
  lcd.print("It's Alive!");

  // initialize the digital pin as an output.
  pinMode(relay, OUTPUT);
  pinMode(button, INPUT);
  pinMode(inputPin, INPUT);     // declare sensor as input
  
  
}

// the loop routine runs over and over again forever:
void loop(){
  //read the value of the button
  buttonValue = digitalRead(button);
  
  // if switch is HIGH - pushed down- change the lights
  if (buttonValue==HIGH){
    
    //changeLights();
    activateMonster();
    
       
    // coundown timer 
    if(runTimer == 1){ 
          lcd.clear();
          lcd.print("TIMER=");
          //Start timer
          timer(); 
       } else {
       }
       runTimer = 0;
       lcd.noDisplay();
       delay(250);
       for(int duration = 0; duration < 100; duration ++){
       } 
       lcd.display();
       delay(250);
       lcd.clear();
       lcd.print("Ready");
       runTimer = 1;
    } // end of coundown timer
  
  // now check PIR
   val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    
    if (pirState == LOW) {
      // we have just turned on
       lcd.setCursor(0, 1);
      lcd.print("Motion detected!");
       lcd.setCursor(0, 0);
      // We only want to print on the output change, not state
      pirState = HIGH;
                         activateMonster();
      // coundown timer 
    if(runTimer == 1){ 
         // lcd.clear();
          lcd.print("TIMER=");
          //Start timer
          timer(); 
       } else {
       }
       runTimer = 0;
       lcd.noDisplay();
       delay(250);
       for(int duration = 0; duration < 100; duration ++){
       } 
       lcd.display();
       delay(250);
       lcd.clear();
       lcd.print("Ready");
       runTimer = 1;
    } // end of coundown timer
      
    
  } else {
    
    if (pirState == HIGH){
      // we have just turned of
       lcd.setCursor(0, 1);
      lcd.print("Motion ended!");
       lcd.setCursor(0, 0);
      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }         
 }  // end check switch loop

    //timer funtion
    void timer() {
       for(int timer = runFor;timer > 0; --timer){
       if(timer >= 10) {
          lcd.setCursor(6,0); 
       } else {   
          lcd.setCursor(6,0);
          lcd.print("0");
          lcd.setCursor(7,0);
       }
       lcd.print(timer);
       lcd.print(" SEC");
       delay(1000);
       lcd.setCursor(0,0);
       
    }  //end of void timer 
}  // end void loop


void activateMonster(){
  // turn relay on for 0.25 sec 
  digitalWrite(relay,HIGH);
  lcd.clear();
  lcd.print("FIRE!");
  delay(250);
  digitalWrite(relay,LOW);
}  // end of void activatemonster