Core Electronics Forum

SWITCH - CASE PROBLEMS...

I NEED TO KNOW HOW TO DO A SWITCH" CASE" FOR THE ATTACHED SCHEMATIC.
I CANNOT SEEM TO GET IT TO WORK. WHEN THE BUTTON IS PUSHED, I WANT IT TO SWEEP TO 50 DEGREES, THE STOP, AND STAY AT 50 DEGREES.
WHEN I FLIP THE SPDT SWITCH, I WANT IT TO MOVE TO 130 AND STAY THERE UNTIL COMMANDED TO MOVE THE OTHER DIRECTION, WITH THE SPDT SWITCH.

MINE KEEPS GOING TO THE 50 DEGREE POSITION, THEN PAUSING, AND RETURNING TO THE OTHER DIRECTION, AND PAUSES, AND JUST KEEPS CYCLING BACK AND FORTH.

CAN YOU PLEASE HELP ME?

MANY THANKS…

TAZ…

3 Likes

Hi Kim,

Can you send through the code you have so far? You should be able to type 3 backticks (usually above tab key), paste your code, and then another 3 back ticks to format it properly.

This one should be pretty simple from the microcontroller’s perspective, just check a digital pin, send a servo signal of a particular duty cycle if the switch is one way, send another if it’s the other way.

Just an if else situation I think
-James

4 Likes

Hey!

If code doesn’t like you, you could consider doing this with a 556 circuit tuned up to the right duty cycles for the angles you want to hit

Just a thought!
-James

4 Likes

Hello, James.

Thank you for responding. I want to explain something, without being taken out of context. I am a retired Digital Design Engineer. I am not a programmer. I am working on a project for a model railroad, so I can set turnout directions with SPDT switches, and hit one button, and they all will move in to position. I am 67 years young, and I learn better, seeing how to do something, and then apply it to other scenarios. I learn faster that way. Would it be possible, to just show me your rendition, using “IF” statements? When the servos move, they should move to 60 degrees, and 130 degrees, respectively. They should only respond when the N.O. push button is pushed, and they should stay in that position, until commanded to return. Am I explaining things good for you?
I TRULY appreciate your method, but, I just need to get this part done. That way I can modify it, and test it in different ways. I learn MUCH faster that way! lol!!!

So, if you could do that for me, I would be ever so grateful…

I do not want to insult you, this is why the explanation. I am a fun loving old man, and I want to get along, and learn.

Many, MANY thanks in advance for this!!!

Taz…

4 Likes

Howdy, James…

That is a great idea, but, then I am not learning the coding I want to learn. But GREAT idea!!!

Taz…

4 Likes

That description is not sufficient as a complete description of the process, although I am sure that you know exactly what you intend. Getting the description right (down to an absolutely pedantic level) is the key to getting the coding right. You need a description something like this:

If the switch is closed (D8 is low) and the button is not pressed (D10 high) then no action is required.
If the switch is closed (D8 is low) and the button is pressed (D10 low) then move the servo to 50.
If the switch is open (D8 is high) then ignore the state of the button and move the servo to 130.

Note that this does not include any command for when the switch changes from open to closed. Do the first two cases take care of this automatically (ie, move to 50 or 130 depending on the button)?

If that description is correct then you can code it as three if statements in the processing loop. The case structure is simply a different way of coding multiple if statements and can be implemented after you get the basic logic working. If you follow that structure and it doesn’t work then the problem might be in getting a compound if (If this AND ALSO that) to work, which can be confusing.

4 Likes

Very well, When D9 is closed, or (LOW), I want the servo to move to the 60 degree position, when the push button is (LOW) or pressed. After the servo reaches the 60 degree position, it must stay at that position, until the the SPDT switch is put in the other position(D8 is LOW), and the push button is depressed bringing D10 LOW. Commanding the servo to move to the 130 degree position, and stay there, until it is commanded to do otherwise.

I can get the servo to move, but, it will NOT stay in the position it is supposed to.

So all I am asking is to show me how to do this. As I have stated, I learn better and faster when I have something to look at with my own eyes. Without sounding snobbish, I am positive the schematic shows exactly what is supposed to happen. That is why I submitted it. My description, may be a little off, but, I am not trying to become a perfect linguist, I simply want to know the best way to do this. It saves TIME, and gives me a better understanding of how it is done.
I truly appreciate your help. But, can we cut to the chase, and show some code? I understand what is IS, but, I do NOT know, how to format it correctly. I need to be shown this, and then I am good for the rest of coding such as this.

Many thanks, Jeff.

Taz…

3 Likes

Note that there is a problem with the schematic - both D8 and D9 are wired to the closed position of the switch. I assumed that you would use one or the other (second rule of programming - don’t assume!) but one of those will have to be removed before it will work. You comment indicates that you will not conect D8.

Changing D8 to D9, that is my second ‘if’ condition. You should show the code you are using for this.

It will stay there until you tell it to do something else.

Do you mean D9 is high? I didn’t read your first description as requiring the button to be pressed again, so change my third condition to
If the switch is open (D9 is high) and the button is pressed (D10 is low) move to 130.

With the connection to D8 removed. That should work. Show the code for that and if it’s still not right then there is probably a problem with the way you have constructed the if statements.

3 Likes

Hey Taz,

Sounds like you’ve already got some code and it’s half working - if you could share what you’ve got we’ll be much better positioned to help. You can just copy and paste your code in like this:

how to paste code




void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

And it will format it like so →

2 Likes

Well, it’s past my bed time, and I get up early, so I will send the code to you guys tomorrow. My wife has Parkinsons, and I am her care taker. She needs me to attend to needs she has problems doing tonight. I want to thank you all for your time tonight. I wll post everything I have tomorrow, and we shall see what happens.
All of you have a good evening. I will be in touch, like I said, tomorrow, as I need to resolve this. Not just for me, but, for the club I am in, and I am in charge of figuring this out for our staging yards.
Be well, and code well!!

Night!

Taz…

5 Likes


#include <Servo.h>

const int button = 5;                         // N.O. Pushbutton
const int sw_Normal_Direction = 6;            // left position of SPDT toggle switch
const int sw_Reverse_Direction = 7;           // right positiion of SPDT Toggle Switch

int pos;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards




void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  pinMode(button, INPUT);                     // sets button to be in the input mode
  pinMode(sw_Normal_Direction, INPUT);        // switch normal setup
  pinMode(sw_Reverse_Direction, INPUT);       // switch Reverse setup

  myservo.write(60);                            // initialize starting servo position

  
}

void loop() {


  int button_State;
  int sw_Normal_Direction_State;
  int sw_Reverse_Direction_State;

  
  
  button_State = digitalRead(button);
  sw_Normal_Direction_State = digitalRead(sw_Normal_Direction_State);
  sw_Reverse_Direction_State = digitalRead(sw_Reverse_Direction);
  
  digitalRead(button_State);
  digitalRead(sw_Normal_Direction_State);
  digitalRead(sw_Reverse_Direction_State);





        if(sw_Normal_Direction_State == LOW  && button_State == LOW){

            for (pos = 60; pos <= 130; pos += 1) { // goes from 60 degrees to 130 degrees
            // in steps of 1 degree
            myservo.write(pos);              // tell servo to go to position in variable 'pos'
            delay(30);                       // waits 20ms for the servo to reach the position

            digitalRead(sw_Normal_Direction_State);

                if(sw_Normal_Direction_State == LOW){

                  myservo.write(pos);

                }              
                  
            }
            
        }


digitalRead(button_State);
digitalRead(sw_Normal_Direction_State);
digitalRead(sw_Reverse_Direction_State);



         if(sw_Reverse_Direction_State == LOW  && button_State == LOW){

            for (pos = 130; pos >= 50; pos -= 1) { // goes from 130 degrees to 60 degrees
                // in steps of 1 degree
                myservo.write(pos);              // tell servo to go to position in variable 'pos'
                delay(30);                       // waits 20ms for the servo to reach the position

                digitalRead(sw_Reverse_Direction_State);
                
                if(sw_Reverse_Direction_State == LOW){

                  myservo.write(pos);

                }

            }
            
       }
  


}
3 Likes

Ok, gentleman. There it is. Not pretty, but, hey, I’m an old fart who doesn’t mind learning.

Just so you know, it only functions on the first function call, then the servo returns to 60 degrees, and I can repeat it, but, when I flip the SPDT Switch, to the second position, it doesn’t even respond. It does not hold its position, in either direction the way I want it to.

Now, PLEASE show me where I am going wrong with this.

Thanks Bunches!! Now it’s up to you gurus, and I will be waiting anxiously for your answer so I can finish this project, and install the system into the club layout.

Best Regards;

Taz…

3 Likes

Your pin assignment don’t match the schematic. The pin numbers are quite different and the code indicates that the direction selection is two push-button switches, not a single on/off switch. The comments below ignore the schematic and assume the code is set up as per the prototype.

You have two different implementations of digitalRead() - only one is correct. So remove the two occurrences of

digitalRead(button_State);
digitalRead(sw_Normal_Direction_State);
digitalRead(sw_Reverse_Direction_State);

You are moving the servo one step at a time and including some additional test (which includes the wrong implementation of digitalRead()) inside the movement loop.

  digitalRead(sw_Normal_Direction_State);
  if (sw_Normal_Direction_State == LOW) {
    myservo.write(pos);

I can’t see what that code is doing, but it should be removed until the program is working in its simplest possible mode. Then you can implement whatever it is that the extra code is trying to do (is it to interrupt the movement before it gets to the end?).

4 Likes

No, I am sorry, I didn’t update the schematic. The goal is the e able to have a series of SPDT switches, and set them up to route a bunch of turnouts on a model train layout, and then push the N.O. Push button, and let the servos set to the proper position for the turnouts to route a train through, from a staging yard.

Ok, then tell me, how do I code this to STOP the servo at the 2 positions I need it to stop at, 60, and 130 degree’s? Nothing I have done, has let me stop it in the correct position. This is as far as I am able to go at this point. I have tried everything I can think of. Remember, I am NOT a genius as you young ones are. If you cannot, or do not want to help, I will go elsewhere. I was told this was THE place to go to get answers. I don’t want or like being toyed with, and right now, I am feeling that is happening. It is very easy to figure out what kind of schematic this would work with, and you DO know it Jeff. Don’t toy with me. Be outright friendly and helpful. If we cannot do this the friendly way, then, maybe someone else needs to step in. I need this to get solved. Not be sent on a wild chase, trying to make me figure every little code letter to do it myself. If I was capable of that, I would not have come here.

FARE ENOUGH?

Thanks.

Now, lets have ANSWERS, and no more questions. I have the questions. I am NOT a school boy in school. You can SHOW me the things that need to be done, I can then SEE them, and I will be able to figure out other things related to this task, by having this one a a reference.

3 Likes

Did you confirm that the pin numbers for the code match the circuit you are now using? There is no need to code the servo to stop after it reaches its position. If it is not stopping in your case then that’s because some additional code is running. That could happen if your switches are not in the state you think they are in, and that could happen if they are not connected to the pins you think they are connected to. That’s why checking the pin connections (or adjusting the schematic so someone can check it for you) is important.

What was the result when you made the changes I suggested? This is what it should look like after those changes, assuming just one SPDT switch for direction.

#include <Servo.h>

const int button = 5;                         // N.O. Pushbutton
const int sw_Direction = 6;            // left position of SPDT toggle switch
int pos;
Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  pinMode(button, INPUT);                     // sets button to be in the input mode
  pinMode(sw_Direction, INPUT);        // switch normal setup
  myservo.write(60);                          // initialize starting servo position
}

void loop() {
  int button_State;
  int sw_Direction_State;
  button_State = digitalRead(button);
  sw_Direction_State = digitalRead(sw_Direction);
  
  if (sw_Direction_State == LOW  && button_State == LOW) {
    for (pos = 60; pos <= 130; pos += 1) { // goes from 60 degrees to 130 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 20ms for the servo to reach the position
    }
  }
  if (sw_Direction_State == HIGH  && button_State == LOW) {
    for (pos = 130; pos >= 50; pos -= 1) { // goes from 130 degrees to 60 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(30);                       // waits 20ms for the servo to reach the position
    }
  }
}

I think that should work, but it is untested. The associated schematic would look like this:

(If you are using a single SPDT switch for the direction then I would expect one pin to be used (6 or 7) and you would test that pin for high or low to indicate switch direction, so it is not clear why you have two inputs for direction.)

3 Likes

That’s a good solution, Jeff. Thanks. Now, I haven’t tried it, but, there is a reason for my madness with 2 connections. I have a switching system, that depends on the 2 inputs for servo direction. How would you go about making it that way?

In other words. I have another application, on a dispatch panel, that uses the 2 input to keep it from running interference, or isolated from it for operating reasons. I have finished the design on, and have boards already made for it. In other words, it may seem redundant, but, It would be good to keep them the same, and the 2 inputs from the SPDT Switch, are tested separately. A single input would be nice, but, I am using it to select another set of inputs, on another controller, that works along side of this one. It will require both points to be read, and checked, very similar to what you have done, but, the way I originally intended ot to. I’ll tell you what. I’ll try to make that work. If I have a problem, and cannot seem to figure it out, I will make another post, and you can work with me on it.

Be back at ya in a little while, and THANK YOU for your help… Time to test it out.

Later…

Taz…

3 Likes

Ok, COOL!! It works ALMOST like I wanted ot too. Thank you. However, I need to eliminate the continuous cycle, if someone decides to hold the push button down. Another part of the system I have designed, needs to have it stay in one state or the other, until the SPDT switch has been cleared from a train passing through the turnout. This of course, I have already got running, and thus, I needed to have this operational, so the other control portion would respond correctly. Hence, I thought by having the 2 inputs from the SPDT switch, I could somehow use it as sort of an interlocking, so that someone, whom ever is operating the Turnouts, doesn’t cause a derailment, by it cycling, while a train is moving through the turnout. There IS a Block detection that could help interlock it.

Ya know, I just figured it out… SEE??? You HELPED me LEARN a new method, Jeff! Now, in MY experience, THAT IS A GREAT LEARNING PROCESS!!!
I KNEW we could figure this out. I just needed someone to show me where I was making the wrong turn. YOU did that. THANK YOU!!!
I look forward to conversing with you again…

Taz…

3 Likes

Before moving the servo, test the value of pos. If it’s already at the end point then skip the move code.

4 Likes

This thread has been an interesting read. Wish I had seen it sooner.
(me old too, but with some experience in coding)
The code below adds the statements @Jeff105671 suggested.
It checks the global variable pos before moving the servo.

Thought it might be easier to see it, always the case for me.
Show me an example, then I can do something with it.

Cheers
Jim

void loop() {
  int button_State;
  int sw_Direction_State;
  button_State = digitalRead(button);
  sw_Direction_State = digitalRead(sw_Direction);
  
  if (sw_Direction_State == LOW  && button_State == LOW) {
    if (pos < 130) {
      for (pos = 60; pos <= 130; pos += 1) { // goes from 60 degrees to 130 degrees
        // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(30);                       // waits 20ms for the servo to reach the position
      }
    }
  }
  if (sw_Direction_State == HIGH  && button_State == LOW) {
    if (pos > 50) {
      for (pos = 130; pos >= 50; pos -= 1) { // goes from 130 degrees to 60 degrees
        // in steps of 1 degree
        myservo.write(pos);              // tell servo to go to position in variable 'pos'
        delay(30);                       // waits 20ms for the servo to reach the position
      }
    }
  }
}
4 Likes

Thank you , James. I will be forever grateful!!

G’day!

:wink:

Taz…

3 Likes