Halloween monster Code

This code is set to move 3 servo slowly and randomly and also gives a random LED blink.
All these are triggered by PIR sensor.
Using Arduino Nano
Can anyone please advice what is wrong with this code?
It does start moving when PIR senses motion.
But servo s move fast, and also gittering..although the parameters I set are for slow movement ??

#include <TrueRandom.h>
#include <VarSpeedServo.h>
  
//amount of time we give the sensor to calibrate(10-60 s ecs according to the datasheet)

int calibrationTime = 30;

//the time when the sensor outputs a low impulse
long unsigned int lowIn;        

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000; 

boolean lockLow = true;
boolean takeLowTime; 

int pirPin = 7;            //digital pin connected to the PIR's output
 
int ledPin =  13;      // the number of the LED pin
int blnkrPin= 11; // output to blinker eyelid motor
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
long OnTime = 400;           // milliseconds of on-time
long OffTime = 500;// initial offtime 
VarSpeedServo NVert,NHoriz,EBall; 
int N1Vert;
int N1Horiz;
int E1Ball;
 
void setup(){
 NVert.attach(5);
  NHoriz.attach(6);
  EBall.attach(3);
  Serial.begin(9600);    //begins serial communication
  pinMode(pirPin, INPUT);
  pinMode(blnkrPin, OUTPUT);

  //give the sensor time to calibrate
  Serial.println("calibrating sensor ");
  for(int i = 0; i < calibrationTime; i++){
    Serial.print(calibrationTime - i);
    Serial.print("-");
    delay(1000);
  }
  Serial.println();
  Serial.println("done");
 
  //while making this Instructable, I had some issues with the PIR's output
  //going HIGH immediately after calibrating
  //this waits until the PIR's output is low before ending setup
  while (digitalRead(pirPin) == HIGH) {
    delay(500);
    Serial.print(".");     
  }
  Serial.print("SENSOR ACTIVE");
}

void loop(){

  if(digitalRead(pirPin) == HIGH){  //if the PIR output is HIGH, turn servo
  
  blinker();
  N1Vert=TrueRandom.random(10,170);
  NVert.write(N1Vert,20,false);//move to random angle 10-170 deg at speed 20
  N1Horiz=TrueRandom.random(10,140);
  NHoriz.write(N1Horiz,20,false);//move to  angle 10-140 deg at speed 20
  E1Ball=TrueRandom.random(30,100);
  EBall.write(E1Ball,30,false);//move to angle 10- 100 deg at speed 30
    
    }
   
    if(lockLow){ 
      //makes sure we wait for a transition to LOW before further output is made
      lockLow = false;           
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis()/1000);
      Serial.println(" sec");
      delay(50);
    }        
    takeLowTime = true;
 

  if(digitalRead(pirPin) == LOW){      

    if(takeLowTime){
      lowIn = millis();             //save the time of the transition from HIGH to LOW
      takeLowTime = false;    //make sure this is only done at the start of a LOW phase
    }
   
    //if the sensor is low for more than the given pause,
    //we can assume the motion has stopped
    if(!lockLow && millis() - lowIn > pause){
      //makes sure this block of code is only executed again after
      //a new motion sequence has been detected
      lockLow = true;                       
      Serial.print("motion ended at "); //output
      Serial.print((millis() - pause)/1000);
      Serial.println(" sec");
      delay(50);
    }
 }
}
void blinker() {
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
 
  if(((ledState == HIGH) && currentMillis - previousMillis >= OnTime))
  
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= (OffTime)))
  {
    ledState = HIGH;  // turn it on
    blnkrPin == ledState;
    
    OffTime = TrueRandom.random(500,3000);
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
    Serial.print("offtime: ");
    Serial.println(OffTime);
    Serial.print("onTime: ");
    Serial.println(OnTime);
  }
}

You have too many things going on here to be able to effectively troubleshoot

Goldenshuttle:

  N1Vert=TrueRandom.random(10,170);

NVert.write(N1Vert,20,false);//move to random angle 10-170 deg at speed 20
 N1Horiz=TrueRandom.random(10,140);
 NHoriz.write(N1Horiz,20,false);//move to  angle 10-140 deg at speed 20
 E1Ball=TrueRandom.random(30,100);
 EBall.write(E1Ball,30,false);//move to angle 10- 100 deg at speed 30

Because you set the wait argument of the write functions to false the servo movement is done in a non-blocking manner. This means it starts the servos moving to the randomly selected angle and then continues on with the rest of the code in your loop(), then loops back to this code again and sets the servo moving to a new random angle, thus the "gittering". That may also be the cause of the fast movements.

This is because I was not fully understanding the effect of false/true ...after I saw ur reply, it is clearer...
I will try using True and hope I get some proper results.tqvm

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Please show how you are powering your NANO and servos.
What model servo, data/spec link..

Thanks.. Tom.. :slight_smile:

I am not so good in sketch...
this is the shield

and the servo s are SG995

the rest is easy to figure out
3 servos at pin 3, 5 and 6
the PIR connects to pin 7

Hi,

Please show how you are powering your NANO and servos?
A picture of your project would help.

Thanks... Tom... :slight_smile:

Here is the foto..shield is powered from 2x 3.8 = 7.6 volts laptop cells

Hi,
Have you tried running your code with just one servo connected, then two servos connected, then three servos connected.

If it is a power problem you should be able to run at least one servo how you want it to.

Have you measured the supply voltage at the servo as they misbehave?

Tom... :slight_smile:

I have replaced the power supply with a well regulated 2 amp current 9 volt supply to the shield..
I also changed the these lines

 N1Vert=TrueRandom.random(10,170);
  NVert.write(N1Vert,20,false);//move to random angle 10-170 deg at speed 20
  N1Horiz=TrueRandom.random(10,140);
  NHoriz.write(N1Horiz,20,false);//move to  angle 10-140 deg at speed 20
  E1Ball=TrueRandom.random(30,100);
  EBall.write(E1Ball,30,false);//move to angle 10- 100 deg at speed 30

with these

 N1Vert=TrueRandom.random(10,170);
  NVert.write(N1Vert,20,ture);//move to random angle 10-170 deg at speed 20
  N1Horiz=TrueRandom.random(10,140);
  NHoriz.write(N1Horiz,20,true);//move to  angle 10-140 deg at speed 20
  E1Ball=TrueRandom.random(30,100);
  EBall.write(E1Ball,30,true);//move to angle 10- 100 deg at speed 30

still getting the servo s to jitter and then move faster than they should:(

how come no one reply..any advice ?

How come no answers?
See reply #7

Hi,
Please answer post #7.

Thanks.. Tom... :slight_smile:

oops sorry...

TomGeorge:
Hi,
Have you tried running your code with just one servo connected, then two servos connected, then three servos connected.
I tried but the one connected or 2 alone show same erratic behavior..the servo shakes for about 2 seconds then moves slowly a little but.

If it is a power problem you should be able to run at least one servo how you want it to.

Have you measured the supply voltage at the servo as they misbehave?
measured power stable at 4.75 Volt. The signal wire reads 250 - 350 mv

Tom... :slight_smile:

Hi,
Can you run this code please.

// Test code to sweep 3 servos, 20 to 100 degrees od arc.
// Tom George

#include <VarSpeedServo.h>


VarSpeedServo NVert;
VarSpeedServo NHoriz;
VarSpeedServo EBall;

int ledPin =  13;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED

int N1Vert;
int N1Horiz;
int E1Ball;

void setup() {
  NVert.attach(5);
  //  NHoriz.attach(6);
  //  EBall.attach(3);
  Serial.begin(9600);    //begins serial communication
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  NVert.write(20, 255, true);
  //  NHoriz.write(20, 255, true);
  //  EBall.write(20, 255, true);
}

void loop()
{
  delay(500);
  // write(degrees 0-180, speed 1-255, wait to complete true-false)
  NVert.write(100, 255, true);      // move the servo to 100, max speed, wait until done
  //  NHoriz.write(100, 255, true);      // move the servo to 100, max speed, wait until done
  //  EBall.write(100, 255, true);      // move the servo to 100, max speed, wait until done
  delay(500);
  NVert.write(20, 30, true);         // move the servo to 20, slow speed, wait until done
  //  NHoriz.write(20, 30, true);         // move the servo to 20, slow speed, wait until done
  //  EBall.write(20, 30, true);         // move the servo to 20, slow speed, wait until done
}

It should just make NVert sweep...

Tom... :slight_smile:

Hi Tom..I just ran the code..yes..Nvert connected to D5 sweeps..the rest not

Hi,
Did it do it smoothy?

If so then uncomment any ref to NHoriz and see if both servos sweep and do it smoothly.

Thanks.. Tom.. :slight_smile:

Thanks Tom
The Nvert moves smoothly without hesitation or jitter. While Nhoriz & Eball stay still..
I will copy the same step to the other servos(NHoriz & Eball) and see if all of them move smoothly.
But how is that going to solve the problem I am having in the original code ?

Hi,
After trying each servo separately, try with two servos, then try with all three operating.
What we are trying to do is establish if your circuit can drive more than one servo reliably.

I know its tedious, but this is fault finding/ debugging.

Thanks.. Tom.. :slight_smile:

Yes indeed, I did as TOM suggested..Now can the the 3 servo s smoothly sweep..this means power supply is sufficient.

Hi,
You have the 3 servos all sweeping together smoothy with my code?

Tom.... :slight_smile: