Go Down

Topic: Activate Stepper Motor with PIR sensor (Read 1 time) previous topic - next topic


Ok, I was trying to make it easier and only write the code for the stepper motor and PIR sensor.  So here is my entire code...that entails recognizing my voice (key work and password), if EasyVR Shield recognizes the pattern then, a solenoid powers on breaking the seal of the fridge door.  Then, the stepper motor takes over the motor and turns 500 steps.
So far so good, the code works.

This is the part where I am stuck.
I want the stepper motor to do -500 steps once the PIR sensor doesn't detect any motion.
My problem is the PIR sensor.  The stepper motor does not do -500 steps once no motion is detected.

as for the code, you might want to ignore it until you see //Activate the stepper motor...that's where I am having trouble.


Code: [Select]
EasyVR access control demo.

  Simple demo showing how to use the EasyVR Shield with Arduino
  to implement an access control system based on voice passwords.

  EasyVR wait for user names in group 1 and, if any name
  is recognized, the system asks for the related password.
  If the password is recognized the access is granted and
  a stepper motor is actuated, if not the access is denied.

  User names and passwords are trained with the EasyVR Commander.
  Transfer the voice recordings into the EasyVR sound table, then
  enter and train user names in group 1 and related passwords in group 16.
  Use long names and passwords to increase recognition performance.
  Moreover, for better security set the recognition level to HARDER using the
  setLevel function.
  With EasyVR Shield, the green LED is ON while the module
  is listening (using pin IO1 of EasyVR).
  Details are displayed on the serial monitor window.

  Example code for the EasyVR library v1.0
  Written in 2011 by RoboTech srl for VeeaR <http:://www.veear.eu>

  To the extent possible under law, the author(s) have dedicated all
  copyright and related and neighboring rights to this software to the
  public domain worldwide. This software is distributed without any warranty.

  You should have received a copy of the CC0 Public Domain Dedication
  along with this software.
  If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.

//EasyVR Shield
#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
  #include "SoftwareSerial.h"
  SoftwareSerial port(12,13);
#else // Arduino 0022 - use modified NewSoftSerial
  #include "WProgram.h"
  #include "NewSoftSerial.h"
  NewSoftSerial port(12,13);

//Stepper Motor - define and declare variables
#include "EasyVR.h"
#include <Stepper.h>
#define motorSteps 200
#define motorPin1 8
#define motorPin2 9
#define motorPin3 10
#define motorPin4 11
#define ledPin 13
Stepper myStepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4);

//Solenoid - declare variable
int solenoidPin = 7;

//PIR Sensor
//int ledPin = 13;
int inputPin = 2;
int pirState = LOW;
int val = 0;

//Sound Commands - not used in this example but still there for reference
#define SND_Access_denied            1
#define SND_Access_granted           2
#define SND_Hello                    3
#define SND_Please_repeat            4
#define SND_Please_say_your_password 5
#define SND_Please_talk_louder       6

//Bridge the EasyVR Shield with the Arduino
EasyVR easyvr(port);
EasyVRBridge bridge;

//EasyVR Shield declare variables
uint32_t mask = 0;
int8_t group = 0;
uint8_t train = 0;
char name[32];

void setup()
  // bridge mode?
  if (bridge.check())
    bridge.loop(0, 1, 12, 13);

  // set the Stepper motor speed at 30 RPMS:
  // initialize the Solenoid digital pin as an output.
  pinMode(solenoidPin, OUTPUT);     
  if (!easyvr.detect())
    Serial.println("EasyVR not detected!");
    for (;;);
  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  int16_t count = 0;
  if (easyvr.getGroupMask(mask)) // get trained user names and passwords
    uint32_t msk = mask; 
    for (group = 0; group <= EasyVR::PASSWORD; ++group, msk >>= 1)
      if (!(msk & 1)) continue;
      if (group == EasyVR::TRIGGER)
        Serial.print("Trigger: ");
      else if (group == EasyVR::PASSWORD)
        Serial.print("Password: ");
        Serial.print("Group ");
        Serial.print(": ");
      count = easyvr.getCommandCount(group);
      for (int8_t idx = 0; idx < count; ++idx)
        if (easyvr.dumpCommand(group, idx, name, train))
          Serial.print(" = ");
          Serial.print(", Trained ");
          Serial.print(train, DEC);
          if (!easyvr.isConflict())
            Serial.println(" times, OK");
            int8_t confl = easyvr.getWord();
            if (confl >= 0)
              Serial.print(" times, Similar to Word ");
              confl = easyvr.getCommand();
              Serial.print(" times, Similar to Command ");
  easyvr.playSound(SND_Hello, EasyVR::VOL_FULL);

void loop()
  int idx_cmd;
  int idx_pwd;
  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
  Serial.println("Say a name in Group 1"); 
  easyvr.recognizeCommand(1); // recognise command in group 1
  while (!easyvr.hasFinished()); // wait for user name
  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx_cmd = easyvr.getCommand(); // get recognised user name

  if (idx_cmd >= 0)
    Serial.print("Name: ");   
    if (easyvr.dumpCommand(1, idx_cmd, name, train))
    easyvr.playSound(SND_Please_say_your_password , EasyVR::VOL_FULL);  // ask for password
    easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening) 
    Serial.println("Say the password");   
    easyvr.recognizeCommand(EasyVR::PASSWORD); // set group 16
    while (!easyvr.hasFinished()); // wait for password
    easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off   
    idx_pwd = easyvr.getCommand(); // get recognised password
    if (idx_pwd >= 0)
      Serial.print("Password: ");     
      if (easyvr.dumpCommand(EasyVR::PASSWORD, idx_pwd, name, train))
        Serial.print(" = ");
      if ( idx_pwd == idx_cmd) // index of username and password are the same, access granted

        Serial.println("Access granted");
        easyvr.playSound(SND_Access_granted , EasyVR::VOL_FULL);   
        //Activate the Solenoid
        digitalWrite(solenoidPin, HIGH);   
        digitalWrite(solenoidPin, LOW);
        //Activate the Stepper motor
        val = digitalRead(inputPin);  // read input value (PIR)
        if (val == HIGH) {            // check if the input is HIGH
            Serial.println("Motion detected!");
            // We only want to print on the output change, not state
            pirState = HIGH;
      } else {
          if (pirState == HIGH){
            Serial.println("Motion ended!");
            // We only want to print on the output change, not state
            pirState = LOW;
      else // index of username and password differ, access is denied
        Serial.println("Access denied");
        easyvr.playSound(SND_Access_denied , EasyVR::VOL_FULL);   
    int16_t err = easyvr.getError();
    if (easyvr.isTimeout() || (err >= 0)) // password timeout, access is denied
      Serial.println("Error, try again...");
      easyvr.playSound(SND_Access_denied , EasyVR::VOL_FULL);
    if (easyvr.isTimeout())
        Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
      Serial.print("Error ");
      Serial.println(err, HEX);         


Look at WHERE you put the code to read the PIR sensor. List all the things that have to happen ON THAT ITERATION OF LOOP() in order for that code to be executed.

Is it likely that all that stuff will happen, in that order, on a single pass through loop()?

You need a state machine (and a lot of changes to that code).

Make a list of states. Name unknown. Name known. Password wrong. Password right. Door open. Door closed. Motion detected. No motion detected. Plus maybe others. Put each of these in circles.

Draw arrows between states where transitions are logical (name unknown to name known is logical; name unknown to door open is not).

Along each arrow, write what needs to happen to trigger that state change, and what happens when the state changes. For instance, from door closed to door open, the door needs to be opened.

Then, write the code to implement each of the transitions (that make sense) when in the appropriate state.


I don't see why I need to change a lot in my code...it works perfectly fine.
Again, the only issue I have is the PIR sensor.  I am having trouble making the stepper motor respond to the PIR sensor not detecting any motion.
Here what my code does as is:
1) I say:"open" (I hear a beep saying it understood), then "fridge" (I hear another beep saying it understood).
2) Linear Solenoid activates
3) Stepper motor starts turning 500 steps
4) Now this is what I need: as soon as the PIR sensor doesn't detect motion, stepper motor turns -500 steps
Keep in mind the PIR sensor is turned on throughout this whole process (detecting motion or not)


You are thinking linearly. Step 2 follows step 1. Step 3 follows step 2.

The Arduino does not.

The Arduino could block when the door has been opened, and do nothing else until there is no motion and it can close the door. But, is that what you really want? It would not listen for new voice commands.

If you want to wait for the PIR sensor to go LOW, you'll need a
Code: [Select]
while(digitalRead(inputPin) == HIGH)
   // Do nothing

block, right after you run the stepper to open the door. Right after this block, you can close the door.


I tried this loop and it works exactly as I wanted it to work
Thank you!!!!!

I added the fucntion in the loop you provided me as follow, to keep the stepper motor at rest.

while(digitalRead(inputPin) == HIGH)

Thank you again for your help PaulS!!!!!

Go Up