Using a rotary switch to trigger outputs biased on change in position

Hello all, I was hoping to get some guidance with an upcoming project I have in mind.

The Theory: Use a rotary switch to select different angles of attack for the rear wing via Arduino controlled linear DC motors. The Arduino would interpret the voltage change from the rotary switch on an analogue input pin, then(this is the part I need help with) if there was an increase in voltage it would trigger output 1 for one second or if it was a decrease in voltage it would trigger output 2 for one second.
output 1 would go to linear DC motor + to 'extend'.
output 2 would go to linear DC motor - to 'retract'.

In my head scratching today I cant find a way to take the values from an analogRead() function and use the positive and negative change in those values to dictate which output triggers. is there a function that can do this? Im still very new to coding, I know enough to know it can be done I just don't know where to look/google/research to get through this block.....

Thanks for any input.

  • Take analogue readings at a suitable interval
  • if the new reading is larger than the previous one trigger output 1
  • if the new reading is smaller than the previous one trigger output 2
  • if absolutely nothing else is happening in the sketch use delay() for the 1 second on timing
  • but much better use millis() timing to implement the on time

Where are you stuck ?

I believe Im stuck more in how to correctly structure the code to compare the new reading to the previous one.

Before you take a new reading save what you read last time as the previous reading in a different variable ready to compare the previous value with new value

I have a library (Toggle) that would work with a 3-position rotary switch
(or toggle switch with center OFF).

  • Could detect the position status 1, 2, or 3
  • Also detects transitions 1⇒2, 2⇒3, 3⇒2 and 2⇒1
  • bounce-free
  • Switch Connections

How many positions is your rotary switch?

okay so check my understanding(sorry for the short hand):
int analogPin = 0;
int val = 0;

void setup()
Serial.begin(9600)
pinMode(2, output)
pinMode(3, output)

void loop()
val = analogRead(analogPin)
if (analogpin > val) digitalWrite(2, high)
delay(1000)
if (analogPin < val) digitalWrite(3, high)
delay(1000)
if(analogPin = val)
delay(1000)

I was planning on a 5 position switch to increase resolution between full retract and full extend. The full range of motion is only going to be 1-4".

I realise that your code is not real but it does not save the previous value before taking a new one

You need something like

start of loop()
  currentValue = analogRead(pin)
  if currentValue > previousValue
    //run code for increased value
  else if currentValue < previousValue
   //run code for reduced value
  previousValue = currentValue  //save the previous value
end of loop()

okay, I see. I guess my next question is then where is 'previousValue' stored? is that a constant that is defined or is that something that needs to be defined when writing the code?

or do I need to write it?

jk i see it previousValue = currentValue

In a variable that you declare

Okay, thank you for the guidance. I'm going to toil away and see if I can come back with the 'Best Script There Ever Was'.

Narrator: "Little did he know: his script would be little more than gibberish and grammatical symbols"

BEWARE! Only the most rare switch does not OPEN the circuit before closing the next circuit. You will ALWAYS have a floating pin for an instant and if your reading of the pin occurs while the circuit is open. you will not have a valid value. Might want to read the pins that are connected to your rotary switch two or three times to be sure you have read the new switch position correctly.

Noted. how can I increase the read frequency? what about duration in between reads?

also: what if mutliple positions were jumped? like from 4v to 2v would the code pulse the output signal twice? or just once?

Now that you are aware of the situation, test to see what you get and what you can do about it. This problem started with the first computer with a rotary switch. Their solution was always to set the rotary switch and then press a button to tell the computer to read the switch position.

I will take this advice and try to apply it to my script. Still working on parts selection, so I dont have anything to physically test just quite..... :grimacing: I do have some extra buttons lying around....

You may want to consider a rotary DIP switch with digital output, for example the RDMAR16P1T from e-Switch. This is a 16-position rotary DIP switch with four digital outputs comprising a 4-bit binary number. They are tiny, so if you are building an aerial drone it may save a lot of weight. I got mine from Digikey.

Why not a rotary encoder with a digital output instead of a rotary switch with an abalog output?

Sorry, I’m old school.
When did a rotary multi position switch require an analog input? ( sure you could use an R2R ladder), or more often just n digital inn puts for each switch position.

The rest of your description seems more like all you need is two buttons. Press one to increase the angle of attack, press the other to decrease it. That isn't selecting.

If you meant a rotary switch with N different preconfigured angles (you did use the word "select"), then the problem is reading a rotary switch, which you could do with N digital inputs or by having the rotary switch be part of a circuit that results in an analog voltage that is different with each switch setting.

google yes!

analog read for rotary switch

So @wubbthe1, what do you really need to do here?

In your first post, the description is ambiguous or I am too sleepy… if there is no feedback from the thing you are extending and retracting, I don't see how the rotary switch would work to select a position.

Extending while you are turning anything one way, and retracting when turning it the other way makes no sense with a potentiometer or a rotary switch - you'd run out of motion. That is why the idea of using a rotary encoder comes up - you can turn that anticlockwise forever, and the thing would be retracting all the while.

a7

Ill add some more project context: This application is for a rear automotive wing. The rotary switch will be operated by the driver. The reason Ive selected a rotary switch is because it is easier for me to understand than a rotary encoder, also it dosent seem worth(and this is with only some background knowledge) learning and writing a script to manage a rotary encoder when I dont need the resolution that the rotary encoder provides. I use the term 'selector switch' loosely in that: yes buttons can do what Im trying to do; however, and this is just my viewpoint. I would believe it would be easier to say: "well I did a lap with the knob on selection 3 and ran 1/10th faster down the straight but I liked the car feel two laps ago when I was on selection 5 because the grip inspired more confidence in the turns" than to try and remember button presses. yes I could add a LCD screen to show different positions but then that adds script complexity and my brain is already spinning. I could also easily add LEDs to show selection, but I would argue I could achieve the same result with a rotary switch with just soldering the LEDs strategically?

This was what I was trying to achieve. My block was how to convert that change in voltage to trigger a digital output biased on an increase, or trigger a second digital output biased on a decrease in voltage. But UKHeliBob pointed me in the right direction by saying make and save a previous value to compare your current value too so you have a change that you can utilize.

Im open to counterpoints, again I havent bought any of the project materials just yet. I have a pile of old electrical components and an Arduino kit that I have been playing with. So if there is a reason I dont know or havent thought of that may be better I'm all ears. I'm trying to keep this simple and straight forward so it wil be theoretically more resilient and easier to service if need be.

Thanks again for all the input guys.

Sorry forgot to roll this in to the last post. I wasn't planning on feed back from the device..... My thought was if I had 1 or 2 DC linear actuators I could then toggle a digital output for Time=(Stroke/N positions)/Actuator Speed to get the actuator to extend. Then to retract I would use a second digital output to retract by the same duration. the motor would be powered by a pair of relays that would receive the Arduino digital output signals. They have some linear actuators that have internal limit switches to prevent it from damaging itself, I was planning to decrease the duration slightly giving myself an overall shorter stroke just to be safe.