3 Stage Switch and a Servo

Hi,

I currently need help writing some code for an upcoming project. This code involves using a three stage switch and one servo. I have written some code already, although I need help with the final element, Switch B (explained below). Please find an image attached of a diagram that helps follow the explanation of what the code is intended to do
So, referencing the diagram, A → Makes the servo go clockwise to 90 degrees (right) and C → makes the servo go anti-clockwise to 90 degrees (left). However, switch B is more complicated, here is a run down of how switch B should work: The switch is at position B, user goes from Switch B to Switch C. Switch C starts to rotate the servo anti-clockwise approximately - 90 degrees to the left. Before it reaches 90 degrees, user goes from the switch C back to Switch B (For purpose of explanation let’s say the servo stopped at 40 degrees). Switch B will then stop the process of anti-clockwise rotation and will check with the servo at which position it is and then store that position as a variable. It will remember it so that if one of the servo moves from where it stopped, the code automatically tells the servo to move back to where it was stopped (which was stored originally as a variable by Switch B).

I understand that my explanation might not be very clear. However, if you do have any questions please do ask. Additionally, I have attached a secretions of some code which I wrote for switch A and C. I am not sure how to add the clockwise/anti-clockwise to the code. I hope it can be of use.

Many Thanks,
UnoA

Servo Explanation.png

The servo cannot feedback it's position to the Arduino, if it's not where the Arduino told it to go last, the Arduino has no way of knowing it.

There are servo's with analog feedback, or you can even hack most Servo's into doing that... http://www.instructables.com/id/Servo-Feedback-Hack-free/

This way you can actually know where a servo is at and not have it jitter when you try to move it precisely or very small amounts...

Kevin77: There are servo's with analog feedback, or you can even hack most Servo's into doing that... http://www.instructables.com/id/Servo-Feedback-Hack-free/

This way you can actually know where a servo is at and not have it jitter when you try to move it precisely or very small amounts...

Thank you very much for your reply. I will look into trying the hack or see if there are any servo's with analog feedback available for sale.

Switch B will then stop the process of anti-clockwise rotation and will check with the servo at which position it is

As has been pointed out your code cannot check the position of a normal servo but if you move the servo in a series of small steps then the program will be able to determine the current position that the servo has been commanded to go to.

UKHeliBob: As has been pointed out your code cannot check the position of a normal servo but if you move the servo in a series of small steps then the program will be able to determine the current position that the servo has been commanded to go to.

Ok, so if I understand correctly instead of instructing the servo to move 90 degrees right in one step, do it in small increments so that the program can determine it's position?

UnoA: Ok, so if I understand correctly instead of instructing the servo to move 90 degrees right in one step, do it in small increments so that the program can determine it's position?

Basically yes, but I was very careful to say that

the program will be able to determine the current position that the servo has been [u]commanded[/u] to go to.

If the servo output is lightly loaded and there is no possibility of it being stalled then this is probably good enough. It would also give you the ability to control the speed of the servo if this is important by introducing a delay (NOTE that I do not mean a delay()) between the servo movements.

You have not said what the application is, how much load is put on the servo, how powerful the servo is, how fast it is required to move or crucially, how the servo will be powered. All of these factors will have a effect on whether you can use a standard servo or need one that provides position feedback.

You could use a standard servo and add a rotary encoder to the output to provide your own feedback without modifying the servo.

UKHeliBob:
If the servo output is lightly loaded and there is no possibility of it being stalled then this is probably good enough.

Thank you for your reply. The servo output is lightly loaded and would not be stalled. The application of this is a robotic arm, which is very light and small. The power of the servo is 4.8V/6V. In terms of speed there is no requirement. The servo will be connected to a breadboard which is connected to an Arduino. The Arduino itself will be battery powered.

The Arduino itself will be battery powered.

and how will the servo be powered ? "from the Arduino 5V and GND pins" is the wrong answer.

The OP has asked in a PM

If it is not powered through the Arduino 5V and GND pins as I thought it should be, I would appreciate if you could explain to me what the correct answer may be.

An Arduino can supply very little current so the servo should be powered by an external power supply with a common GND with the Arduino.

UKHeliBob:
An Arduino can supply very little current so the servo should be powered by an external power supply with a common GND with the Arduino.

Okay, so where does this go now in terms of code for Switch B?

Reading your requirement again this

It will remember it so that if one of the servo moves from where it stopped, the code automatically tells the servo to move back

is definitely going to need some feedback from the servo or an encoder attached to it.

However, if the servo is continually told to stay at a given position it will firmly resist any movement and stay resolutely where it is. In that case someting like what is outlined in the pseudo code below may work.

start of setup()
  servoPos = 0  //the servo must start in a known position
  move servo to servoPos using servoWrite()
end of setup

start of loop()
  if switchA becomes pressed
    movingA = true
    movingC = false
  end if

  if switchC becomes pressed
    movingC = true
    movingA = false
  end if

  if movingA is true
    increment servoPos
    if target position is reached set movingA to false
  end if

  if movingC is true
    decrement servoPos
    if target position is reached set movingC to false
  end if

  if switchB becomes pressed
    movingA = false  //stop the servo moving
    movingC = false
  end if
  
  move servo to servoPos to either update or maintain its position

end of loop()

Note that I have left out the boring stuff like declaring variables, including libraries and setting pinModes()s and that the logic may be full of holes anyway !

UKHeliBob: Note that I have left out the boring stuff like declaring variables, including libraries and setting pinModes()s and that the logic may be full of holes anyway !

Thank you very much for the help. I appreciate you taking the time to explain theory as well as the feedback servo's. Finally, if I understand correctly the pseudo code is like an outline or a blueprint for the code?

if I understand correctly the pseudo code is like an outline or a blueprint for the code?

That is correct. It is a way of exploring the logic and flow of a program but needs expanding into real code. For instance a single line such as   if switchA becomes pressedwould become several lines of real code that tests the current state of the switch and whether it has changed since the last time it was checked and is currently pressed.

UKHeliBob:
That is correct. It is a way of exploring the logic and flow of a program but needs expanding into real code.

I have since taken the pseudocode and tried to transform it. I have tried reading and using resources, although I think the code is far from accurate. Below is what I have started. I am struggling with how to transform “if switchA becomes pressed”, how to assign SwitchA, SwitchB and SwitchC as inputs it will recognize as well as “ServoPos.” Any help correcting the code or advice would be much appreciated.

#include<Servo.h>
const int SWITCH=7;
int val=0;
int old_val=0;
int state = 0; 


void setup()
{
  pinMode(SWITCH,INPUT);
  Servo myservo;
  myservo.attach(9);
  servoPos = 0  //the servo must start in a known position
  myservo.write(servoPos)
} 

void loop()
{
  val = digitalRead(SWITCH);

  if SWITCH(A) becomes pressed
    state = 1 - state;
}

old_val = val; 

  if (state==1){
    myservo.write(90)
  } else {
    break
  }  
}

Good for you for trying. We now have something to work with

There are many things to put right as you know.

Firstly you will need to use 3 separate pins for the switch inputs, so choose 3 pins, declare 3 global variables with appropriate names and assign pin numbers to them. Perhaps switchAPin, switchBPin and switchCPin, but you decide. Do not use pins 0 or 1.

In setup() use pinMode() to set the 3 pins as inputs using INPUT_PULLUP as the mode. If this does not make sense then read up on it.

Wire the 3 switches to the 3 pins such that when activated they take the pins LOW

Now let's deal with detecting the change of pin state from HIGH to LOW ie, the switch has just been activated. To keep it simple you will need 6 new variables. The variables should be global and have names to indicate their purpose is to hold the current and previous state of switches A, B and C. Hence 6 variables which should all be given an initial value of HIGH. There is a neater way that only uses 2 variables but let's leave that for later.

In loop() write the code to read the current state of switch A and put it into one of your 6 variables. Compare it with the previous state held in another of the 6 variables and if it has changed and is now LOW print a message saying so. The StateChangeDetection example in the IDE will show how to do this and how to save the current state as the previous state ready for the check next time through loop()

Do nothing else in your program. I know that it is frustrating but you cannot write it all at once.

Once you have a program detecting that switch A has changed state and is now LOW add code to do the same for switches B and C and come back for more advice.

I have had a PM from the OP asking for more help.

Let’s start with detecting that a switch has changed state rather than when it is in a particular state. Have a look at the StateChangeDetection example in the IDE and think about applying the principles to your program.