Servo programming problem

Hi Guys,

I have been racking my brain trying to get this sketch to work properly but still not 100%.

The servos are being used to open boom gates for my model railway crossing. When the train triggers the first mini reed switch the lights flash and the boom gate comes down and stays down until the second mini reed switch is triggered and the boom gate comes up and the lights stop flashing. I think i may have the servo parts wrong.

Can anyone see what I may have done wrong?

#include <Servo.h>

Servo myservo;

const int A = 8;                    // Amber LED
const int R1 = 9;                   // 1st Red LED
const int R2 = 10;                  // 2nd Red LED
const int G = 11;                   // Green Active LED
const int R = 12;                   // Red inactive LED
const int BL = 13;                  // Building Lights
const int BL2 = 14;                 // Building Lights2
const int buttonPin = 2;            // pushbutton pin
const int S1Lights = 3;         // BL Switch
const int S2Lights = 4;         // BL2 Switch

int buttonState = 0;                // variable for reading the pushbutton status
int running = 0;
int long interval = 400;
long previousMillis = 0;
int R1State = HIGH;
int pos = 0;

void setup() {
  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(R, OUTPUT);
  pinMode(A, OUTPUT);
  pinMode(BL, OUTPUT);
  pinMode(BL2, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(S1Lights, INPUT);
  pinMode(S2Lights, INPUT);
  myservo.attach(7);
  digitalWrite(buttonPin, HIGH);

}

// the loop routine runs and stops after last command
void loop() {

  if (digitalRead(S1Lights) == HIGH) {
    Lights(); // calls Lights Function
  }
  
  if (digitalRead(S2Lights) == HIGH) {
    Lights2(); // calls Lights2 Function
  }
    
  
  int buttonState = digitalRead(buttonPin);

  // the switch has been activated and the program can run 
  if (buttonState == HIGH && running == 0) {
    int running = 1;
    digitalWrite(A, HIGH);
    delay(1000);
    digitalWrite(A, LOW);
    tone(6, 550, 1000); // play SOUND
    digitalWrite(G, HIGH); // turn on GREEN LED
    myservo.write(90);
    delay(1000);
    digitalWrite(G, LOW); // turn off GREEN LED
    delay(250);
    buttonState = digitalRead(buttonPin);
    while(buttonState == LOW && running == 1)  {

      // Timer used instead of delay to allow input to be read at the same time
      unsigned long currentMillis = millis(); 

      if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;

        if (R1State == HIGH){ // Switches lights over
          digitalWrite(R1, LOW);
          digitalWrite(R2, HIGH);
          R1State = LOW;
        }
        else {
          digitalWrite(R1, HIGH); // Switches lights over
          digitalWrite(R2, LOW);
          R1State = HIGH;
        }
      }
      else {
        // Terminates program and switches off lights if the trigger input is detected
        buttonState = digitalRead(buttonPin); 
        if (buttonState == HIGH){
          digitalWrite(R1, LOW); // turn the LED off
          digitalWrite(R2, LOW); // turn the LED off
          tone(6, 450, 1000); // play SOUND 
          digitalWrite(R, HIGH); // turn on RED LED
          myservo.write(0);
          delay(2500);
          digitalWrite(R, LOW); // turn off RED LEDD
          int R1State = LOW;
          delay(5000);
          int running = 0;
          break;
        }
      }
    }
  }
}

Can anyone see what I may have done wrong?

Can you please describe what happens as opposed to what should happen ?
The program would be easier to understand if you used more meaningful names for the variables and pins.

const int buttonPin = 2;            // pushbutton pin
const int S1Lights = 3;         // BL Switch
const int S2Lights = 4;         // BL2 Switch

How are these switches wired? Are you using external resistors? If so, are they pullup or pulldown, and why? Why not use the internal pullup resistors and simple wiring?

And, as UKHeliBob asked, what do these names mean?

  if (buttonState == HIGH && running == 0) {
    int running = 1;

If you worked for me, I'd kick your ass all over the place for using a local variable with the same name as a global variable. Why are you doing it?

      // Timer used instead of delay to allow input to be read at the same time

What a load of rubbish. The else block is full of delay()s.

          int running = 0;
          break;

Another local variable that immediately goes out of scope. Why bother?

The demo code that I wrote in the first post in this Thread might be a useful model.

...R

The servos are being used to open boom gates for my model railway crossing. When the train triggers the first mini reed switch the lights flash and the boom gate comes down and stays down until the second mini reed switch is triggered and the boom gate comes up and the lights stop flashing.

You might try the below servo toggle code. Wire the reed switches (assuming normally open) on each side of the crossing in parallel. Set the crossing with gates normally open, then when the train magnet actuates the first switch the gate servo closes the gate, and when the train crosses the second reed switch, the gate opens.

//zoomkat servo button toggle test 4-28-2012

#include <Servo.h>
int button = 5; //button pin, connect to ground to move servo
int press = 0;
Servo servo;
boolean toggle = true;

void setup()
{
  pinMode(button, INPUT); //arduino monitor pin state
  servo.attach(7); //pin for servo control signal
  digitalWrite(5, HIGH); //enable pullups to make pin high
}

void loop()
{
  press = digitalRead(button);
  if (press == LOW)
  {
    if(toggle)
    {
      servo.write(160);
      toggle = !toggle;
    }
    else
    {
      servo.write(20);
      toggle = !toggle;
    }
  }
  delay(500);  //delay for debounce
}

PaulS and UKHeliBob cause i'm still a bit of a noob, do you mean that it would be easier to understand if I used the function of each variable as the name instead of R1, R2, buttonPin etc.

For instance

const int CrossingReady = 8;
const int RightLEDs = 9;
const int LeftLEDs = 10;
const int CrossingActive= 11;
const int CrossingInactive = 12;
const int BuildingLights = 13;
const int BuildingLights2 = 14;
const int CrossingTrigger = 2;
const int BuildingLightsSwitch = 3;
const int BuildingLights2Switch = 4;

Yes.

Your objective should be to write code that you can understand fully on the first read-through after a 6 month break.

...R

thanks Robin

now i need to rebuild the whole thing so you guys can better understand what im doing

Well I've rebuilt the crossing prototype and I remember now that the only problem i have with the boom gate servo is that I need it to move more like an actual boom gate instead of straight down and straight up as it is doing now

the only problem i have with the boom gate servo is that I need it to move more like an actual boom gate instead of straight down and straight up as it is doing now

You'll need to describe that like you would to a blind person. After all, we can't see what you are talking about.

The servo doesnt move in small increments. It's either up or down theres no slowly moving up or down

e.g. its like switching on a light it's either on or off unless you install a fader then you get the gradual change from light to dim and vice versa the more you turn he knob

The servo doesnt move in small increments. It's either up or down theres no slowly moving up or down

First, servos don't move. They rotate.

Second, they rotate from a current position to a new position, when you send them a new position. If the current position is 0 degrees, and you send it a new position of 90 degrees, of course it's going to hustle to get there. If you give it a new position of 1, then later a new position of 2, then later a new position of 3, etc. it will rotate slowly.

aussiefantom:
The servo doesnt move in small increments. It's either up or down theres no slowly moving up or down

e.g. its like switching on a light it's either on or off unless you install a fader then you get the gradual change from light to dim and vice versa the more you turn he knob

That's a better explanation, but I had a giggle when you described the light going on and off and had just read Paul's suggestion to describe it to a blind person !

What you need to do is use servo.write(nextPosition); instead of using servo.write(finalPosition); then wait a little, increment nextPosition and do it again. DO NOT use delay() to wait a little because the whole program will wait. Instead use the principle used in the BlinkWithoutDelay example in the IDE. Note the start time of an action and check each time through loop() if the required interval has passed. If so, then do something (update nextPosition and move the servo). If not, then carrying on doing other things such as monitoring the track for train movements, flasing LEDs or whatever.

Ok so looking at the program I posted earlier that is still very basic (variable names etc.) can you give me a few tips on how to go about it cause to me it sounds like I need to add separate timers and that's confused the hell out of me

Have you looked at the servo sweep example that comes with the Arduino IDE? Does that meet your need? If not, explain what it fails to do that you want done.

...R

hi there guys, im having trouble figuring out how to add a reed switch to my existing project. At the moment i use a IR remote to control leds and a servo but i want to do away with the IR Remote and activate it with the reed and a magnet. Can someone please advise or amend what i have done already.

#include "VarSpeedServo.h"
#include "IRremote.h" // IR library
int RECV_PIN = 2; // IR Decoder To this Pin
IRrecv irrecv(RECV_PIN); // Start the library
decode_results results;
VarSpeedServo helmet1;
VarSpeedServo mask1;
int Leye = 10;
int Reye = 11;
int tmp = 0;
void setup()
{
pinMode(Leye,OUTPUT);
pinMode(Reye,OUTPUT);
digitalWrite(Leye,HIGH);
digitalWrite(Reye,HIGH);
Serial.begin(19200);
Serial.println("IRON MAN Control system Ready . . ");
delay(500);
Serial.println("Remote decode values follow :");
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
digitalWrite(3,LOW);
digitalWrite(4,HIGH);
irrecv.enableIRIn(); // Start the IR receiver
//upMask();
}
void loop()
{
if (irrecv.decode(&results))
{
Serial.println(F("ID_DET"));
dump(&results);
irrecv.resume(); // Receive the next value
}
}
void upMask()
{
digitalWrite(Leye,LOW);
digitalWrite(Reye,LOW);
delay(250);
helmet1.attach(9);
mask1.attach(6);

helmet1.slowmove(0,0); //faceplate up position (left angle/right speed)
mask1.slowmove(130,180);
delay(500); //Delay to allow mask to move to UP possition.

helmet1.detach();
mask1.detach();
}
void downMask()
{
helmet1.attach(9);
mask1.attach(6);

helmet1.slowmove(0,90); //50 to move slower at end of travel - stops the SLAM
mask1.slowmove(0,130);
delay(1500); //Wait for a bit before lighting the eyes
helmet1.detach();
mask1.detach();

digitalWrite(Leye,HIGH);
digitalWrite(Reye,HIGH);
delay(100);

digitalWrite(Leye,LOW);
digitalWrite(Reye,LOW);
delay(100);

digitalWrite(Leye,HIGH);
digitalWrite(Reye,HIGH);
delay(100);

digitalWrite(Leye,LOW);
digitalWrite(Reye,LOW);
delay(100);

digitalWrite(Leye,HIGH);
digitalWrite(Reye,HIGH);

}

void dump(decode_results *results)
{
tmp = results->value, HEX;
Serial.print("TMP : ");
Serial.println(tmp);
if( (tmp == 54080))
{
Serial.println("upMask();");
upMask();
}
if( (tmp == 25681))
{
Serial.println("downMask();");
downMask();
}

}

shane742:
do away with the IR Remote and activate it with the reed and a magnet. Can someone please advise or amend what i have done already.

Can you describe in plain language (not code) how the IR Remote does what you want the reed switch to do?

I presume you know how to get the state of the reed switch?

...R