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
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:(
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
// 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
}
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.