Go Down

Topic: Servo control (Read 383 times) previous topic - next topic

tgsimmons

Jan 14, 2018, 12:35 am Last Edit: Jan 14, 2018, 02:24 am by tgsimmons Reason: to post my code correctly
Hello,  I'm brand new to the Arduino and am starting with a simple project but have run into something that I can't figure out.  The project is controlling three servos hooked to blast gates on a home shop dust collection system.  The servos are switched using three interlocked switches (only one switch can be on at a time).  My program was initially successful but in testing, I found that the larger of the three blast gates was struggling to open so I decided to open the two smaller blast gates first (to relieve pressure) then shortly afterward, open the larger blast gate and after a short delay, close the two small blast gates.  Here's the code I used to do that (full code is below):
Code: [Select]
if (sw4inState == LOW)  
   {
   servoMS.write(MSOpen);
   servoBS.write(BSOpen);
   delay(200);
   servo4in.write(bigOpen);
   delay(1000);  
   servoMS.write(MSClosed);
   servoBS.write(BSClosed);

This code worked fine through the "servo4in.write(bigOpen);" command but nothing happened after that when the two smaller gates should have closed.  I tried varying the second delay (up to 10 seconds) just to let things settle but the smaller gates never closed until the "sw4inState" switch was closed.  Any idea of why this is not responding properly?  I'd also appreciate any input as to a better way to do this or suggestions for cleaning up the code.

Thanks for your help.

Here's the entire program.
Code: [Select]

/*
Controlling three servos using three switches
*/

#include <Servo.h>

Servo servo4in;  // create servo object to control a servo
Servo servoBS;
Servo servoMS;

//three control switches, interlocked so only one can be used at a time
int sw4in = 14;   //switch for four inch hose
int swBS = 15;    //switch for bandsaw hose
int swMS = 16;    //switch for mitersaw hose

int sw4inState = 0;
int swBSState = 0;
int swMSState = 0;

//The following sets the range of the three servos with respect to blast gate
//opening, it is adjusted for each individual servo/blast gate.

int bigOpen = 55;   //4in hose:  0 is open, 180 is closed
int bigClosed = 170;

int BSOpen = 90;    //BandSaw  180 is open, 0 is closed
int BSClosed = 10;

int MSOpen = 75;    //MiterSaw  180 is open, 0 is closed
int MSClosed =  5;


void setup() {

 pinMode(sw4in, INPUT);
 pinMode(swBS, INPUT);
 pinMode(swMS, INPUT);
 
 servo4in.attach(5);
 servoBS.attach(6);
 servoMS.attach(9);

 servo4in.write(bigClosed);  //closes all three blast gates
 servoBS.write(BSClosed);
 servoMS.write(MSClosed);
}

void loop() {

sw4inState = digitalRead(sw4in);  //reads the status of all three switches
swBSState = digitalRead(swBS);
swMSState = digitalRead(swMS);


//the following code responds to the three switches, LOW is on, HIGH is off.

if (sw4inState == LOW)  
   {
   servoMS.write(MSOpen);
   servoBS.write(BSOpen);
   delay(200);
   servo4in.write(bigOpen);
   delay(1000);  
   servoMS.write(MSClosed);
   servoBS.write(BSClosed);
   }

 if (swBSState == LOW)
   { servoBS.write(BSOpen);}
   
 if (swMSState == LOW)
   {servoMS.write(MSOpen);}
     

if  (sw4inState == HIGH)
   {servo4in.write(bigClosed);}  

if (swBSState == HIGH)
   {servoBS.write(BSClosed);}
   
if (swMSState == HIGH)
   {servoMS.write(MSClosed);}

   }

outsider

#1
Jan 14, 2018, 01:11 am Last Edit: Jan 14, 2018, 01:16 am by outsider
Do you have external pullup resistors (10k) on the switch pins? If not, replace lines 31 - 33 with:
Code: [Select]

  pinMode(sw4in, INPUT_PULLUP);
  pinMode(swBS, INPUT_PULLUP);
  pinMode(swMS, INPUT_PULLUP);

Assuming you have the switches wired between pin and GND. Do you?
If switches are wired between pin and 5V, you should have pulldown resistors from pin to GND.

outsider

#2
Jan 14, 2018, 01:29 am Last Edit: Jan 14, 2018, 01:44 am by outsider
Also, if you want all gates closed at startup, replace the last lines in setup() with:
Code: [Select]

    //attaches and closes all three blast gates
  servo4in.write(bigClosed);
  servo4in.attach(5);
  servoBS.write(BSClosed);
  servoBS.attach(6);
  servoMS.write(MSClosed);
  servoMS.attach(9);
}

BTW: Here's how to post code so it appears in a scrollable box like above:
HowToPostCode

tgsimmons

Hi outsider, Yes, I've got pullup resistors on the switches and they work fine.  I'm wondering if there's a bug in the Servo Library code that won't let opposite commands happen so close together.
In this short section of code (by the way, thanks for the heads-up in how to post code), when the switch is flipped, two gates should open then 0.2 sec later another gate should open then one second later, the first two gates should close.  In practice, the last function doesn't happen, the two gates don't close.  Something is causing this to hang up and I'm not sure how to correct it.

Code: [Select]
if (sw4inState == LOW)
    {
    servoMS.write(MSOpen);
    servoBS.write(BSOpen);
    delay(200);
    servo4in.write(bigOpen);
    delay(1000);
    servoMS.write(MSClosed);
    servoBS.write(BSClosed);
    }

outsider

In setup(), add:
Code: [Select]
Serial.begin(9600); // set Serial monitor baud rate to match
Then, change this block:
Code: [Select]

if (sw4inState == LOW) 
   {
   servoMS.write(MSOpen);
   servoBS.write(BSOpen);
   delay(200);
   servo4in.write(bigOpen);
   delay(1000); 
   servoMS.write(MSClosed);
   servoBS.write(BSClosed);
   }

To:
Code: [Select]
if (sw4inState == LOW)
    {
    servoMS.write(MSOpen);
    servoBS.write(BSOpen);
    delay(200);
    servo4in.write(bigOpen);
    delay(1000);
    servoMS.write(MSClosed);
    servoBS.write(BSClosed);
    Serial.print(servoMS.read);
    Serial.print("\t");
    Serial.print(servoBS.read);
    Serial.print("\t");
    Serial.println(servo4in.read);
    }

And see what Serial monitor shows.

outsider

One question, have you tried the sketch without the blower running?

TomGeorge

#6
Jan 14, 2018, 01:11 pm Last Edit: Jan 14, 2018, 01:12 pm by TomGeorge
Hi,
Welcome to the forum.

What model Arduino are you using?
What are your servos, link to data/specs?

What is your power supply?

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

Thanks.. Tom.. :)
Everything runs on smoke, let the smoke out, it stops running....

wildbill

Quote
I'm wondering if there's a bug in the Servo Library code that won't let opposite commands happen so close together.
I'd strongly suggest that you abandon that line of thinking. There could indeed be bugs there, but given how much use that library gets, I highly doubt you found one.

There's much more likelihood that your issue is wiring, power or your own code. Of course, if you have found a bug and can provide example code that demonstrates it, the library maintainer will probably be pleased to hear about it, but look to your own stuff first.

tgsimmons

Thanks to everyone who has responded.  Here are my answers to your questions/comments:

outsider:  I just now tried the serial monitor code you suggested and get a "invalid use of non
-static member function" message from the last line of the code "Serial.println(servo4in.read);"  I haven't yet tried to figure out what that means, I'll work on it, it's all part of the learning process :)
Nearly all of my testing has been done without the blower running so that rules out interference from the motor.

TomGeorge:  I'm using a SparkFun ProMicro 5v/16MHz.  The servos are Hitec HS-425BB.  Currently for testing, I'm using a benchtop 5volt, 5amp power supply.  Here's the circuit:

wildbill:  I know that was a bit brash of me, being a newbie, for speculating that it could be a bug in the library, sorry about that.  It's just that everything else worked fine and I was trying to analyze what could be hanging things up with such a simple block of code.

TomGeorge

Hi,
If you run the servos, with no mechanical load, do they function correctly?

Can you monitor the 5V supply while your program faults?

Have you tried writing code with just that block ONLY in it and the relevant input switch and servo output?
In other word just bit of code that ONLY does the "sw4inState == LOW" block.

You may have to put some initial positions for the servos in the void setup(), so you will see them move to the programmed positions.

Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Power_Broker

Two random things:

1) Why don't you have denouncing code for the buttons/switches?

2) Can you format your code correctly and then repost? Your tabs are off (I think) and it may be confusing yourself or us. Indentation conventions are not as trivial as most beginners think. They help code readability and make bugs easier to find.
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

aarg

Two random things:

1) Why don't you have denouncing code for the buttons/switches?
Because they haven't committed any heresy?
  ... with a transistor and a large sum of money to spend ...
Please don't PM me with technical questions. Post them in the forum.

outsider

Quote
Because they haven't committed any heresy?
:smiley-lol:

outsider

#13
Jan 14, 2018, 10:53 pm Last Edit: Jan 14, 2018, 11:04 pm by outsider
OOPS!, my bad, try it now:
Code: [Select]
#include <Servo.h>

Servo servo4in;  // create servo object to control a servo
Servo servoBS;
Servo servoMS;

//three control switches, interlocked so only one can be used at a time
int sw4in = 14;   //switch for four inch hose
int swBS = 15;    //switch for bandsaw hose
int swMS = 16;    //switch for mitersaw hose

int sw4inState = 0;
int swBSState = 0;
int swMSState = 0;

//The following sets the range of the three servos with respect to blast gate
//opening, it is adjusted for each individual servo/blast gate.

int bigOpen = 55;   //4in hose:  0 is open, 180 is closed
int bigClosed = 170;

int BSOpen = 90;    //BandSaw  180 is open, 0 is closed
int BSClosed = 10;

int MSOpen = 75;    //MiterSaw  180 is open, 0 is closed
int MSClosed =  5;


void setup() {

 pinMode(sw4in, INPUT);
 pinMode(swBS, INPUT);
 pinMode(swMS, INPUT);
 
    //attaches and closes all three blast gates
  servo4in.write(bigClosed);
  servo4in.attach(5);
  servoBS.write(BSClosed);
  servoBS.attach(6);
  servoMS.write(MSClosed);
  servoMS.attach(9);
}


void loop() {

sw4inState = digitalRead(sw4in);  //reads the status of all three switches
swBSState = digitalRead(swBS);
swMSState = digitalRead(swMS);


//the following code responds to the three switches, LOW is on, HIGH is off.

 if (sw4inState == LOW)
    {
    servoMS.write(MSOpen);
    servoBS.write(BSOpen);
    delay(200);
    servo4in.write(bigOpen);
    delay(1000);
    servoMS.write(MSClosed);
    servoBS.write(BSClosed);
    Serial.print(servoMS.read());
    Serial.print("\t");
    Serial.print(servoBS.read());
    Serial.print("\t");
    Serial.println(servo4in.read());
    }
   
 if (swBSState == LOW)
   { servoBS.write(BSOpen);}
   
 if (swMSState == LOW)
   {servoMS.write(MSOpen);}
     

if  (sw4inState == HIGH)
   {servo4in.write(bigClosed);} 

if (swBSState == HIGH)
   {servoBS.write(BSClosed);}
   
if (swMSState == HIGH)
   {servoMS.write(MSClosed);}

   }

outsider

Quote
This code worked fine through the "servo4in.write(bigOpen);" command but nothing happened after that when the two smaller gates should have closed.
What is the state of the swBS and swMS switches at this time? Did you try flipping them to the opposite state?

Go Up