Cant get rid of glitches

First of all I'd like to say thanks to anyone who takes the time to read this.

I'm working on my first robot and am having trouble identifying the source of my glitches.

The robot is supposed to lay prone and when it detects motion, it stands, looks around (servo sweep), then goes prone again.

Everything works fine according to the sketch, but at some point the whole thing glitches out and the servos go bonkers.

I'm assuming its a coding problem, since I'm a noob, so that's where I'll start. Here's what I got so far.

#include <Servo.h>

Servo frlg;
Servo fllg;
Servo rrlg;
Servo rllg;
Servo sweep;

int pos = 45;

int pirPin = 12;
int pirPos = 13;

int calibrationTime = 30;

long unsigned int lowIn;
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;

void setup() {
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(pirPos, OUTPUT);
digitalWrite(pirPin, LOW);
digitalWrite(pirPos, HIGH);

frlg.attach(2);
fllg.attach(4);
rrlg.attach(7);
rllg.attach(8);
sweep.attach(9);

Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}

void loop() {
if(digitalRead(pirPin) == HIGH) {
for (pos = 45; pos < 90; pos += 1)
{
frlg.write(pos);
delay(4);
}

for (pos = 135; pos > 90; pos -= 1)
{
fllg.write(pos);
delay(4);
}

for (pos = 45; pos < 90; pos += 1)
{
rrlg.write(pos);
delay(4);
}

for (pos = 135; pos > 90; pos -= 1)
{
rllg.write(pos);
delay(4);
}

{
delay(1500);
}

{
for(pos = 90; pos < 150; pos += 1)
{
sweep.write(pos);
delay(15);
}
for(pos = 150; pos > 25; pos -= 1)
{
sweep.write(pos);
delay(15);
}
for(pos = 25; pos < 90; pos += 1)
{
sweep.write(pos);
delay(15);
}

{
delay(1500);
}
}

for (pos = 90; pos > 45; pos -= 1)
{
frlg.write(pos);
delay(4);
}

for (pos = 90; pos < 135; pos += 1)
{
fllg.write(pos);
delay(4);
}

for (pos = 90; pos > 45; pos -= 1)
{
rrlg.write(pos);
delay(4);
}

for (pos = 90; pos < 135; pos += 1)
{
rllg.write(pos);
delay(4);
}

if(lockLow) {
lockLow = false;
Serial.println("---");
Serial.print("motion detected at ");
Serial.print(millis()/1000);
Serial.println(" sec");
delay(50);
}
takeLowTime = true;

if(takeLowTime) {
lowIn = millis();
takeLowTime = false;
}

if(!lockLow && millis() - lowIn > pause){
lockLow = true;
Serial.print("motion ended at "); //output
Serial.print((millis() - pause)/1000);
Serial.println(" sec");
delay(50);
}

}
{
delay(2000);
}
}

Thanks again.

How are the servos powered? They should have their own power supply.

Your symptoms could easily be caused by the servos drawing so much current that they cause the Arduino voltage to drop which then causes the Arduino to brown-out or reset.

...R

Hey Robin2 thanks for the prompt response.

I have the servos hooked to a breadboard which is powered. Only the signal wires from the servos are going to the arduino.

The only thing my arduino is currently powering is the PIR.

I can't make sense of your program. Please provide an explanation of how it is supposed to work.
Have you identified the place in the code where the trouble starts?

You have a lot of unnecessary {} and these two lines don't make sense following one after the other

         takeLowTime = true;
        
         if(takeLowTime) {

Also, please use code tags for posting code - that way there are no smileys and it is easy to copy to my text editor.

#include <Servo.h>

Servo frlg;
Servo fllg;
Servo rrlg;
Servo rllg;
Servo sweep;

int pos = 45;

int pirPin = 12;
int pirPos = 13;

int calibrationTime = 30;

long unsigned int lowIn;
long unsigned int pause = 5000;

boolean lockLow = true;
boolean takeLowTime;


void setup() {
	Serial.begin(9600);
	pinMode(pirPin, INPUT);
	pinMode(pirPos, OUTPUT);
	digitalWrite(pirPin, LOW);
	digitalWrite(pirPos, HIGH);
 
	frlg.attach(2);
	fllg.attach(4);
	rrlg.attach(7);
	rllg.attach(8);
	sweep.attach(9);
 
	Serial.print("calibrating sensor ");
	for(int i = 0; i < calibrationTime; i++){
		Serial.print(".");
		delay(1000);
		}
	Serial.println(" done");
	Serial.println("SENSOR ACTIVE");
	delay(50);
	}
 

 

void loop() {
	if(digitalRead(pirPin) == HIGH) {
	for (pos = 45; pos < 90; pos += 1)
	{
		frlg.write(pos);
		delay(4);
	}
	
	for (pos = 135; pos > 90; pos -= 1)
	{
		fllg.write(pos);
		delay(4);
	}
	
	 for (pos = 45; pos < 90; pos += 1)
	{
		rrlg.write(pos);
		delay(4);
	}
	
	for (pos = 135; pos > 90; pos -= 1)
	{
		rllg.write(pos);
		delay(4);
	}
	
	{
		delay(1500);
	}
	
	{
	for(pos = 90; pos < 150; pos += 1) 
	{                                   
		sweep.write(pos);             
		delay(15);                       
	}
	for(pos = 150; pos > 25; pos -= 1)   
	{                               
		sweep.write(pos);               
		delay(15);                       
	}
	for(pos = 25; pos < 90; pos += 1)   
	{                               
		sweep.write(pos);               
		delay(15);                       
	}
 
	{
		delay(1500);
	}
}
	
	for (pos = 90; pos > 45; pos -= 1)
	{
		frlg.write(pos);
		delay(4);
	}
	
	for (pos = 90; pos < 135; pos += 1)
	{
		fllg.write(pos);
		delay(4);
	}
	
	for (pos = 90; pos > 45; pos -= 1)
	{
		rrlg.write(pos);
		delay(4);
	}
	
	for (pos = 90; pos < 135; pos += 1)
	{
		rllg.write(pos);
		delay(4);
	}
	
	
	if(lockLow) {
		lockLow = false;           
		 Serial.println("---");
		 Serial.print("motion detected at ");
		 Serial.print(millis()/1000);
		 Serial.println(" sec");
		 delay(50);
		 }         
		 takeLowTime = true;
		
		 if(takeLowTime) {
			lowIn = millis();
			takeLowTime = false;
		 }
		 
		 if(!lockLow && millis() - lowIn > pause){
			lockLow = true;                       
			Serial.print("motion ended at ");      //output
			Serial.print((millis() - pause)/1000);
			Serial.println(" sec");
			delay(50);
			}
			
	}
	{
	delay(2000);
	}
}

...R

Hey R2 sorry bout that code post, new to the forums. That code came from the servo sweep in examples, I just played with it some, so i really dont know what most of it means lol.

How its supposed to work:

After the PIR calibrates it goes "prone", for lack of a better word. Once the PIR detects movement, the robot stands, looks around (servo sweep), and then goes prone again.

It's usually right after the "sweep" where it wigs out.

DGLTD:
How its supposed to work:

I was hoping you would provide a more detailed "walk through" of the program so that I could understand the logic. For example (complete fiction)

The next few lines read and save the temperature of the porridge

In this part we use the temperature to decide whether to start stirring
We keep stirring until Daddy Bear comes home

...R

Hey R2 sorry for the delayed response, was trying to figure things out on my own. hope this is a better explanation than my last post.

I still have to add the servo sweep but you should get the general idea. Thanks again.

#include <Servo.h>

Servo fr; //front right leg
Servo fl; // front left leg
Servo rr; // rear right leg
Servo rl; // rear left keg
Servo hd; // head

int blue = 2;  // led RGB
int green = 4; 
int red = 3; 

int pirPin = 8;  // PIR input
int pirPow = 13; // PIR power

int pos = 0;
int calibrationTime = 10;  // calibration time for PIR


void setup() {
  Serial.begin(9600);
  pinMode(blue, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(pirPin, INPUT);
  pinMode(pirPow, OUTPUT);
    
  fr.attach(5);
  fl.attach(6);
  rr.attach(7);
  rl.attach(9);
  hd.attach(10);
  
  fr.write(25);  // these next lines set robot in prone/ready position
  fl.write(165);
  rr.write(165);
  rl.write(15);
  hd.write(90);
  
  Serial.print("calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      delay(1000);
      }
    Serial.println(" done");
    Serial.println("SENSOR ACTIVE");
    delay(50);
  
  digitalWrite(pirPin, LOW);
  digitalWrite(pirPow, HIGH);
  digitalWrite(blue, LOW);
  digitalWrite(green, HIGH);  // LED on to show ready status
  digitalWrite(red, LOW);
}

void loop() {
  if(digitalRead(pirPin) == HIGH) {  // here, when the PIR detects motion, the robot "stands" looks around (runs servo sweep sketch) then goes prone again
    digitalWrite(green, LOW);
    digitalWrite(red, HIGH);
    fr.write(40);
    fl.write(150);
    rr.write(150);
    rl.write(30);
    }
else{
  digitalWrite(red, LOW);
  digitalWrite(green, HIGH);
   fr.write(25);
  fl.write(165);
  rr.write(165);
  rl.write(15);
  hd.write(90);
}
}

I would add a delay of at least two seconds after each position change to allow the servos time to settle.

The PIR status may be changing before the servos reach the intended position.
You might also add a println statement to show the status of PIR at the top of the loop() function.

Another tip is to rename your variables with more descriptive terms.
It will make reading and trouble-shooting easier.

DGLTD:
Only the signal wires from the servos are going to the arduino.

You will also need to hookup the GND from the arduino to your GND of the servos and the GND of the power supply.

You have pirPin defined as an input. Why are you writing to it in setup() ?

There is nothing wrong with writing to all the servos in quick succession as long as you know that the Arduino does not wait for the first move to finish before it starts the next move.

With that in mind it would be a good idea (essential?) to have a wait period between successive reads of pirPin so that all the servo motion will have finished before pirPin is read for the next time.

I would develop this sort of project in two parts.
In one part I would use hard-coded values for pirPin to test that the servo motion behaves properly.

In the other part I would make sure that I could read the PIR reliably - probably just by priniting the values to the Serial Monitor. I would be especially checking for poor detection including bounces.

...R

Hi,

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

Including your power supply for the servos thanks.
What is your servo supply?

Tom..... :slight_smile: