Go Down

Topic: Rotary Switch Programming  (Read 488 times) previous topic - next topic

aaroncotton

I have a Teknic MCPV servo motor that I am trying to control with an arduino uno. The servo has its own software and the ability to move to four set position using Boolean logic of two inputs (inputA and InputB). I am trying to more the servo to these 4 preset locations through the use of a 4 position rotary switch and I am having some issues. I have googled how to program a rotary switch and all I can ever find are codes dealing with rotary encoders.

I have the 4 position leads of the switch plugged into the analog inputs A0-A3

I have done the tutorials but I know next to nothing about coding although I am doing my best to change that.

Teknic has an example code that has the servo that makes the servo move to the positions based on a time delay, is there anyway I could modify their code to work with a 4 position rotary switch?

After some googling I think I could make it work with an "if" "else if" code maybe but I am not sure how to define the switch to the arduino.

Sorry if this is long and rambley I am Just trying to give as much detail as possible and not waste anyones time.

Code: [Select]
/*
  TekTips1 - program to highlight Arduino wiring to a Teknic ClearPath integrated servo motor
  Author is Abe Amirana, 7/10/2017   
  Program uses a "MCVC" (Motion Control Velocity Control) ClearPath servo motor
  Operating Mode is the "Ramp Up/Down to Selected Velocity" (uses 2 input bits to control 4 velocities)
  - View operational mode video for further information on this specific Operational Mode:
  https://www.teknic.com/watch-video/#Opmode5
     
  TekTips Video: Wiring a ClearPath motor to an Arduino micro controller
  www.youtube.com/blahblahblah
*/

//Wire colors refer to a standard Teknic ClearPath controller cable
const int Enable = 6; // ClearPath ~enable input; +enable = BLU wire; -enable = ORN wire
const int InputA = 8; // ClearPath Input A; +InputA = WHT wire; -InputA is BRN wire
const int InputB = 9; // ClearPath Input B; +InputB = BLK wire; -InputB = YEL wire
const int HLFB = 4; // ClearPath HLFB Output; +HLFB = GRN wire; -HLFB = RED wire
const int myLED = 13; // Arduino on-board LED

int DwellTime = 500; // desired time for ramp and constant velocity

// ============================================================================================
// put your setup code here, to run once:
void setup()
{
  pinMode(Enable, OUTPUT);
  pinMode(InputA, OUTPUT);
  pinMode(InputB, OUTPUT);
  //pinMode(HLFB, INPUT_PULLUP);
  pinMode(HLFB, INPUT);
  pinMode(myLED, OUTPUT);

  // start off by ensuring thet the motor is disabled before proceeding
  digitalWrite(Enable, LOW);
  delay(10);

  // set the two outputs to their initial states
  digitalWrite(InputA, LOW);
  digitalWrite(InputB, LOW);
  digitalWrite(myLED, LOW);
 
  // toggle ~enable, read HLFB & set on-board LEDs - this clears any safety shutdowns & activates motor's power stage
  digitalWrite(Enable, HIGH);
  delay(15);
  while(digitalRead(HLFB) == !LOW) {
    delay(20);
  }
  if (digitalRead(HLFB) == LOW) {
    digitalWrite(myLED, HIGH);
    delay(200);
  }
}
// end of setup code

// put your main code here, to loops indefinitely:
void loop()
{
  for (int i = 0; i<3; i++) {
    // command to the first velocity setting
    digitalWrite(InputA, HIGH);
    digitalWrite(InputB, LOW);
    while(digitalRead(HLFB) == LOW) {   // wait for HLFB to go false (move has started)
    }
    while(digitalRead(HLFB) == !LOW) {  // wait for HLFB to go true (Move Done = true)
    }
    delay(DwellTime);

    // command to the second velocity setting
    digitalWrite(InputA, LOW);
    digitalWrite(InputB, HIGH);
    while(digitalRead(HLFB) == LOW) {
    }
    while(digitalRead(HLFB) == !LOW) {
    }
    delay(DwellTime);
 
    // command to the third velocity setting
    digitalWrite(InputA, HIGH);
    digitalWrite(InputB, HIGH);
    while(digitalRead(HLFB) == LOW) {
    }
    while(digitalRead(HLFB) == !LOW) {
    }
    delay(DwellTime);
 
    // command to the forth and final velocity setting (back to zero velocity)
    digitalWrite(InputA, LOW);
    digitalWrite(InputB, LOW);
    while(digitalRead(HLFB) == LOW) {
    }
    while(digitalRead(HLFB) == !LOW) {
    }
    delay(DwellTime);

    DwellTime = DwellTime - 250;
  }
  DwellTime = 500; 
  delay(DwellTime);
}
// end of main code, will loop indefinitely:

DKWatson

Rather than using four pins, have you thought about maybe stringing say 1K resistors between the switch poles and using it as a 4-position voltage divider then reading an analog value from one pin (0-255, 256-511, 512-767, 768-1023)?
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

aaroncotton

Thank you for the reply,

I have seen a video on YouTube about that, where a guy had a 12 position switch  going to only 1 analog input. I guess I don't understand enough about electricity, it looked like the resisters were daisy chained between the switch position terminal posts, so how is it that the circuit doesn't see the maximum resistance all of the time?

UKHeliBob

Quote
I have the 4 position leads of the switch plugged into the analog inputs A0-A3
Where does the other lead from the switch connect to ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

DKWatson

#4
Mar 23, 2018, 05:36 pm Last Edit: Mar 23, 2018, 05:38 pm by DKWatson
0V                                         5V
---1K---1K---1K---1K---1K---
          |         |         |         |
      1V       2V       3V       4V

Connect the four taps to your switches 'outputs' and the common to the analog input.


Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

dougp

Either way you get the inputs you're going to have to convert to a two bit code:

Code: [Select]

if(digitalRead(A0) == 1){  // discrete digital inputs - A0 thru A3?
 outputCode = b00000000;
}

// and so on for next three inputs

// or

if(posnOneLowLimit <= analogRead(A0) and analogRead(A0) <= posnOneHiLimit){
 outputCode = b0000000;
}

// and so on for next three input values
Everything we call real is made of things that cannot be regarded as real.  If quantum mechanics hasn't profoundly shocked you, you haven't understood it yet. - Niels Bohr

No private consultations undertaken!

Paul_KD7HB

Make provision for the open circuit that happens when you move the rotary switch from one detent to another. There are rare rotary switches that "make" the new connection before "breaking" the previous connection, but you probably would have to special order it.

Paul

aaroncotton

Make provision for the open circuit that happens when you move the rotary switch from one detent to another. There are rare rotary switches that "make" the new connection before "breaking" the previous connection, but you probably would have to special order it.

Paul
Can you elaborate on this please? What provisions do I need? Sorry if this is a dumb question, I have very limited experience coding

Paul_KD7HB

Can you elaborate on this please? What provisions do I need? Sorry if this is a dumb question, I have very limited experience coding
The common pin of your switch will need either a pull-up resistor to give you a certain, specific voltage value when the switch is in between contacts. This will also effect your resistor tree.

Or you can read the voltage value again and again if the first results do not match any of your designed voltage values, and stop reading when you get a good value.

Paul

UKHeliBob

Unless you are short of pins then I would suggest not using the resistor ladder approach.  Simply wire each pole of the 4 pole switch to a digital input and the common lead to GND.  Use a pinMode() of INPUT_PULLUP and write the program to detect when an input pin goes LOW and act on it.

Using a single analogue input pin and a resistor ladder is very clever and economical but more complicated than the OP needs I suggest.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

outsider

#10
Mar 24, 2018, 03:29 am Last Edit: Mar 24, 2018, 03:30 am by outsider
You could get away with 2 input pins and 2 diodes.

UKHeliBob

Quote
You could get away with 2 input pins and 2 diodes.
I still think that 4 discrete pins is the way to do this unless there are compelling reasons to do it any other way.

By all means explore other methods once you understand the basics, but keep it simple to start with.  As I never did get an answer from the OP as to where the common switch contact was connected to I think that simple is best for now.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Paul_KD7HB

I still think that 4 discrete pins is the way to do this unless there are compelling reasons to do it any other way.

By all means explore other methods once you understand the basics, but keep it simple to start with.  As I never did get an answer from the OP as to where the common switch contact was connected to I think that simple is best for now.
Four discrete pins allow software to take care of the open time while the switch is being rotated.

Paul

Go Up