Adding additional functions to servo rotation project

Hi,

This project will rotate a model railroad coal dumper when the button is pressed. Dump the coal, then rotate it back to home position.

I would like to add the two additional functions to this project:

I need to include two IR sensors to make sure the rotating part is clear prior to rotating. (can I just parallel the two sensors and just use one pin?)
I need to include an additional servo to actuate during the rotation to lock the car down. then release when the platform is back to home position.

any help is much appreciated.

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
#define servoPin 3 //~
#define pushButtonPin 2 

int angle =10;    // initial angle  for servo
int angleStep =2;
const int minAngle = 10;
const int maxAngle = 180;

int buttonPushed =0;

void setup() {
  // Servo button demo by Robojax.com
  Serial.begin(9600);          //  setup serial
  myservo.attach(servoPin);  // attaches the servo on pin 3 to the servo object
  pinMode(pushButtonPin,INPUT_PULLUP);
   Serial.println("Robojax Servo Button ");
}

void loop() {
  if(digitalRead(pushButtonPin) == LOW){
    buttonPushed = 1;
  }
   if( buttonPushed ){
  // change the angle for next time through the loop:
  angle = angle + angleStep;

    // reverse the direction of the moving at the ends of the angle:
    if (angle <= minAngle || angle >= maxAngle) {
      angleStep = -angleStep;
       buttonPushed = 0;
    }
    myservo.write(angle); // move the servo to desired angle
      Serial.print("Moved to: ");
      Serial.print(angle);   // print the angle
      Serial.println(" degree");    
  delay(100); // waits for the servo to get there
   }

  
}

yes, two sensors can be wired so that they both must be active or non-active and it sounds like they indicate a condition that needs to be true to operate the dumper

sounds like you need a sequencer

  • wait for start button and verify IR sensor condition
  • move locking arm
  • rotate car to dump
  • wait a moment (delay())
  • rotate car to upright position
  • release locking arm

i suggest a sub-function with servo, state and target position arguments to move the servos to the target positions during various stages of the sequence

consider

# define PinButton      A1
# define PinSensor      A2

#include <Servo.h>

struct ServoSt {
    int     pin;
    int     pos0;
    int     pos1;
    long    stepDelay;

    const char * desc;

    int     pos;
    Servo   servo;
} servos [] = {
    { 3, 10, 20,  30,  "arm" },
    { 4, 90, 100, 100, "rotate" },
};
#define N_SERVO     (sizeof(servos)/sizeof(ServoSt))

enum { S_ARM, S_ROT };
enum { Pos_0, Pos_1 };

// -----------------------------------------------------------------------------
void
posServo (
    int     servoId,
    int     posId )
{
    ServoSt  *s   = & servos [servoId];
    int       pos = s->pos0;

    if (Pos_1 == posId)
        pos = s->pos1;

    Serial.print   ("posServo: ");
    Serial.print   (s->desc);
    Serial.print   (" ");
    Serial.println (pos);

    int dir = s->pos < pos ? 1 : -1;

    for ( ; s->pos != pos; )  {
        s->pos += dir;
        s->servo.write (s->pos);
        Serial.println (s->pos);
        delay (s->stepDelay);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (LOW == digitalRead (PinButton))  {
        if (LOW == digitalRead (PinSensor))
            Serial.println ("obstruction");
        else  {
            posServo (S_ARM, Pos_1);
            posServo (S_ROT, Pos_1);
            delay (1000);
            posServo (S_ROT, Pos_0);
            posServo (S_ARM, Pos_0);
            Serial.println (" complete");
        }
    }
}


// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);          //  setup serial

    ServoSt  *s   = & servos [0];
    for (unsigned n = 0; n < N_SERVO; n++, s++)  {
        s->servo.attach (s->pin);
        s->pos = s->pos0;
        s->servo.write (s->pos);
    }

    pinMode (PinButton, INPUT_PULLUP);
    pinMode (PinSensor, INPUT_PULLUP);

    Serial.println ("Coal Dumper");
}

Greg,

Thank you very much. This is fun to play with.

Is there a way to speed up the speed steps?

long    stepDelay;

consider

the 30 in { 3, 10, 20, 30, "arm" }, is the stepDelay. it and the other values: pin, pos0, pos1 can be changed in that initialization line. same for the "rotate" serv

Greg,

Thank you for your help. Everything works great. I will move forward with the construction of the rotary dumper!

It may be some time, but I will return to this thread to post results.

Thanks!

Greg,

Can you help with these two LED functions? I was attempting to add 2 LEDs to the code. When the IR sensor is obstructed, send Pin 11 (RED) to low, otherwise send pin 10 (Green) to low. I am wanting to get one of those push buttons that has the LED lights in it so the operator can see the status on the button.

# define PinButton      A1
# define PinSensor      A2

#include <Servo.h>

struct ServoSt {
    int     pin;
    int     pos0;
    int     pos1;
    long    stepDelay;

    const char * desc;

    int     pos;
    Servo   servo;
} servos [] = {
    { 3, 10, 180,  5,  "arm" },
    { 4, 10, 180, 25, "rotate" },
};
#define N_SERVO     (sizeof(servos)/sizeof(ServoSt))

enum { S_ARM, S_ROT };
enum { Pos_0, Pos_1 };

// -----------------------------------------------------------------------------
void
posServo (
    int     servoId,
    int     posId )
{
    ServoSt  *s   = & servos [servoId];
    int       pos = s->pos0;

    if (Pos_1 == posId)
        pos = s->pos1;

    Serial.print   ("posServo: ");
    Serial.print   (s->desc);
    Serial.print   (" ");
    Serial.println (pos);

    int dir = s->pos < pos ? 1 : -1;

    for ( ; s->pos != pos; )  {
        s->pos += dir;
        s->servo.write (s->pos);
        Serial.println (s->pos);
        delay (s->stepDelay);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (LOW == digitalRead (PinButton))  {
        if (LOW == digitalRead (PinSensor))
            digitalWrite (11, LOW);// IF SENSOR ON TURN ON RED LED
        else  {
            posServo (S_ARM, Pos_1);
            delay (2000);           //Delay between clamp and rotate
            posServo (S_ROT, Pos_1);
            delay (3000);           //Delay to hold car upside down
            posServo (S_ROT, Pos_0);
            delay (2000);           //Delay between rotate and clamp
            posServo (S_ARM, Pos_0);
            digitalWrite (11, HIGH); // OTHERWISE TURN ON GREEN LED
        }
    }
}



// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);          //  setup serial

    ServoSt  *s   = & servos [0];
    for (unsigned n = 0; n < N_SERVO; n++, s++)  {
        s->servo.attach (s->pin);
        s->pos = s->pos0;
        s->servo.write (s->pos);
    }

    pinMode (PinButton, INPUT_PULLUP);
    pinMode (PinSensor, INPUT_PULLUP);
    pinMode (10, INPUT_PULLUP); //GREEN LED
    pinMode (11, INPUT_PULLUP); //RED LED 

    Serial.println ("Coal Dumper");
}

several things

  • define symbol names for the LEDs up near PinSensor
#define PinLedRed    10
#define PinLedGreen 11
  • define them as OUTPUT not INPUT
    pinMode (PinLedRed, OUTPUT);
    pinMode (PinLedGreen, OUTPUT);
  • i think what you're you looking for is the red/green led to indicate when the car is in position and to use the sensor to prevent operation if not in position (i don't know how the sensors are wired, when HIGH/LOW is clear)
void loop ()
{
    int  sensor = digitalRead (PinSensor);
    if (HIGH == sensor)  {
        digitalWrite (PinLedRed,   LOW);
        digitalWrite (PinLedGreen, HIGH);
    }
    else {
        digitalWrite (PinLedRed,   HIGH);
        digitalWrite (PinLedGreen, LOW);
    }

    if (LOW == digitalRead (PinButton))  {
        if (HIGH == sensor)  {
            posServo (S_ARM, Pos_1);
            delay (2000);           //Delay between clamp and rotate
            posServo (S_ROT, Pos_1);
            delay (3000);           //Delay to hold car upside down
            posServo (S_ROT, Pos_0);
            delay (2000);           //Delay between rotate and clamp
            posServo (S_ARM, Pos_0);
            digitalWrite (11, HIGH); // OTHERWISE TURN ON GREEN LED
        }
    }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.