1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Using a rotary encoder in place of a potentiometer

Discussion in 'Electronic and hardware generally' started by Alexey, Apr 26, 2017.

  1. Alexey

    Alexey Well-Known Member

    Joined:
    Sep 23, 2014
    Messages:
    452
    Occupation:
    Electronics Technician
    Location:
    Adelaide, Australia
    Balance:
    8,061Coins
    Ratings:
    +620 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    Hello all!

    To make a long story short I will start with this, I am never happy with anything I build....
    I have decided to build a simulator using 4 linear actuators to provide pitch, roll and heave.
    What has this got to do with rotary encoders you may ask? Well as I have been building and testing my actuator I have come across a really annoying problem. The problem is accurately reading the position of the actuator and also mounting a potentiometer along with the gear reduction etc. I found this to be really annoying and to top it off my 10 turn pots ended up being unreliable as they would partially loose contact with the track at some points and just generally poor performance all round. Sometimes they would work and sometimes they would misbehave. So I looked into the usual things such as stupidly expensive pots, string pots but they all had this annoying part mounting them accurately and adjusting travel distances with gears etc.

    My actuator:

    [​IMG]
    [​IMG]

    The easiest answer in my mind is using a rotary encoder as they turn forever and you don't have to worry about gearing them down. That is where I remember reading a few people asking "why can't we use rotary encoders?" and the answer was always "because they take up too much headroom in the processor". So why not just give the reading of the encoder to a separate processor then?

    Lets get straight into the meat of things, here is a video of me using a rotary encoder to move the feedback line in the SMC3 utils. I will go through things in a bit more detail after the video.

    To explain the video:
    at first I have already set the range of the encoder so that 5v is at count = 1000 which can be read on the 7 segment display. As I go through the range of the encoder you will see the feedback line follow the encoder count. Then I change my range to be 5v at 2000 counts. meaning you can have whatever rotational range and set the lower and upper points manually. In even more simpler terms, you can have 10 rotations or 100 rotations and the program will automatically adjust the output to suit 0 -5v.
    To demonstrate that, I adjust the encoder to be at 644 counts and reset the upper limit, you can see the feedback line shoot straight up to max when I activate the switch (not seen in video but you can hear me click it).



    A picture of my somewhat messy setup:
    [​IMG]

    So, lets get into the setup.
    [​IMG]

    At this very early stage the setup requires a separate arduino to read the encoder and output it to the arduino that runs the SMC3 code. At the moment I am using an arduino UNO but a nano could be used in its place as they are a cheaper board. I have a nano and I will test the code when I get around to fishing it out of its hiding place.... somewhere....

    The encoder is a 100 cpr unit that I salvaged from an old antenna rotator that was being thrown out. Having a low cpr is actually quite useful for an actuator because the arduino can easily keep up with the counts + rpm and is still very accurate. There is only 255 positions in the whole range of motion, the encoder counts are mapped to 0 - 255. So having a 1000 cpr encoder is only just putting strain on the processor.

    lastly there is two limit switches which are activated on the lowest and highest part of desired travel range.
    These can be activated by hand or setup up to be activated by a pre-determined point on the actuator/lever arm.


    How the code works:

    The encoder is read via a hardware interrupt routine which makes it very fast and accurate. The two encoder channels A and B are connected to pins 2 & 3. Every time the encoder outputs a pulse the code determines the direction of the encoder and will either add to the encoder count or decrease the encoder count. The count can go negative, which is undesirable but wont really hurt anything

    To have a live update of where the encoder count is I have used an arduino multi function shield with a seven segment display. I write the encoder count directly to the display. (as seen in the video)
    I have written a part in the code so that negative numbers are not displayed because negative numbers do not display correctly on the shield. Only 0000 is displayed when the count is negative.

    Now I will get into the calibration. There are variables stored for the maximum and minimum count numbers. To set these limits there are the two limits switches. When the motion range of the actuator/lever arm is at its lowest point you can press the lower limit switch and this will ZERO the encoder count. meaning it resets the encoder count from wherever it was to 0000. This sets the lowest point that your actuator/lever arm will sit.
    Then the upper limit switch can be activated at the highest point of travel of the actuator/lever arm. It doesn't even have to be set an min/max as you can set the range to be wherever you want (but still within the mechanical limit of motion range). At this stage the encoder count will be however many pulses have been read by the arduino, there is no set count number. I used 1000 and 2000 just for ease of demonstration in my video.
    To give a real world figure, my actuator has 32 turns in the desired travel range. This will theoretically give me 3200 encoder counts over the range.

    Now to getting to the output stage.

    To turn these counts into a 0 - 5v signal we must convert the counts to a PWM value. Why PWM?
    When PWM is read with an analogue meter you will actually read a 0 - 5v ouput with a 0 - 100% PWM
    A PWM signal is sent in arduino by using the analogWrite() function. This has a range of 0 to 255 (0 - 100%).
    So how does an encoder count of 3200 squeeze into 255? We can map the value! The map function will divide out the encoder count into a desired range (0 - 255). Example: I can have a 1 to 1 ratio where the encoder is set to a max count of 255. So every encoder count is a direct change to the PWM. Or I can have a 2 to 1 ratio where I set the encoder max count to 510 where every second encoder count changes the PWM.

    The code also has a constrain function where it will enforce an output of 0 - 255. Just in case of the cheeky code doing weird things.

    Unfortunately just outputting a PWM signal is not enough to get that analogue signal to mimic a potentiometer. When connected to the arduino running SMC3 you can see that the feedback pot actually picks up the PWM pulses and thus just goes from min to max rapidly. The get the signal we want a filter must be used. It could also be called a DAC. A simple RC filter is used as shown in the diagram. BUT! this is still not enough... Along with the DAC comes noise which makes the feedback line oscillate a small amount. not a huge amount but enough to make a motion simulator vibrate rapidly. To eliminate this we have to use a software filter function called smoothing.
    The function has to be inserted into the SMC3 code itself. This function is inserted at the point where the feedback pot is read. it averages the reading of the input and then inserts it back into the feedback pot value.
    This creates what looks like a smooth response as seen in the video. It's hard to tell if there is any oscillation left in the feedback.

    This is as far as I have gotten so far. I will post the code and the amended SMC3 code so that anyone curious can test it out for themselves. unfortunately I forgot my damn USB that has the code so I will do that tomorrow.
    • Like Like x 3
    • Creative Creative x 3
    • Informative Informative x 2
    • Winner Winner x 1
    Last edited: Apr 26, 2017
  2. RandomCoder

    RandomCoder Active Member Gold Contributor

    Joined:
    Feb 19, 2017
    Messages:
    185
    Occupation:
    Control Engineer
    Location:
    UK
    Balance:
    1,674Coins
    Ratings:
    +142 / 0 / -0
    I like your style, but two things come immediately to mind...
    1. Why go to all the extra trouble of trying to mimic a potentiometer when the first UNO which is directly connected to the encoder already knows the positional value of the encoder? Why not just communicate this to the second UNO using I2C? I've not got any experience in doing this but it would seem like a more logical approach.
    2. If you power the second UNO with a battery backup then you could retain the encoder position and not need to initialise on startup.
    Just a couple of ideas which I hope will prove useful.
    • Useful Useful x 2
  3. Alexey

    Alexey Well-Known Member

    Joined:
    Sep 23, 2014
    Messages:
    452
    Occupation:
    Electronics Technician
    Location:
    Adelaide, Australia
    Balance:
    8,061Coins
    Ratings:
    +620 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    I can answer your first question with ease, because I am a coding newb.
    My code consists of a mash of different arduino examples and things I have pillaged from the internet.
    Reading through I2c, I can't see why it would be advantageous for me to use it at this stage. Maybe at a later stage where I could modify the SMC3 code to use the encoder count as positional control but at this stage it is set up for reading a potentiometer.

    Come to think about it.... I could map the encoder count to a 0 - 1023 (same as the range of reading a pot with analogRead).... Which could be handled by the arduino running SMC3...

    You've got me thinking now.....

    With the battery setup I was thinking of using something like a nicad battery so that every time the power supplies are turned on they can recharge the battery. This could eliminate the need to re calibrate every time the arduino is turned on.



    As promised, attached is the arduino code.

    Line changes in the SMC3 code is as follows:

    94, 96 and 97 = setup

    smooth function is added to line 214 and ends at line 231.

    The insertion of the smoothing function happens from line 1659 and ends in line 1661.

    Attached Files:

  4. Zed

    Zed VR Simming w/Reverb Gold Contributor

    Joined:
    Apr 4, 2017
    Messages:
    1,040
    Location:
    USA
    Balance:
    5,840Coins
    Ratings:
    +1,040 / 4 / -0
    My Motion Simulator:
    2DOF, DC motor, JRK
    Hey Alexey, serial comms are pretty easy on the Arduino. The data is sent in bytes but there are commands to read multiple bytes if you want more than 8 bit resolution. You might want to home brew a packet of sorts or do some kind of handshake or something to make sure everything stays aligned as the transmitter starting up before the receiver could have the receiver not interpreting high and low bytes correctly if the transmitter just sends a stream of bytes. Single byte data is trivial. It's just as soon as you get least and most significant bytes that you have to know which is which. The Arduino supports high data rates so you can get updated data across really fast if you go that way. Cool project!
  5. Alexey

    Alexey Well-Known Member

    Joined:
    Sep 23, 2014
    Messages:
    452
    Occupation:
    Electronics Technician
    Location:
    Adelaide, Australia
    Balance:
    8,061Coins
    Ratings:
    +620 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    Hi Zed, I've looked into the I2c bus that is available on the arduino and it can work quite effectively, I will certainly take up advice given by @RandomCoder . One arduino can be the master and another be the slave where the master will request data and the slave will receive the request and then send the requested data. Using the I2c bus It can have multiple slaves (multiple encoders) rather than a one to one serial.

    I've just got to figure out how to pad the data being sent through to make up for bits not being used when the encoder count is low.

    Cheers
    • Like Like x 1
  6. RandomCoder

    RandomCoder Active Member Gold Contributor

    Joined:
    Feb 19, 2017
    Messages:
    185
    Occupation:
    Control Engineer
    Location:
    UK
    Balance:
    1,674Coins
    Ratings:
    +142 / 0 / -0
    This is usually overcome by sending a header byte, the master will reject all data received until it sees the header byte and then it knows to expect the data which is often followed by an end byte to signify the end of the data. Different systems do it different ways but the theory is pretty much the same. I've not had a play with Arduino's yet but I'm looking forward to the opportunity when I get my own rig started.
    • Agree Agree x 1
  7. Alexey

    Alexey Well-Known Member

    Joined:
    Sep 23, 2014
    Messages:
    452
    Occupation:
    Electronics Technician
    Location:
    Adelaide, Australia
    Balance:
    8,061Coins
    Ratings:
    +620 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    Oh I forgot to mention. In the arduino code for reading the encoder, there is a library included in line 1 which I forgot to delete.
    If anyone tests this code you will have to remove line 1 and also change line 56 from "digitalReadFast2" to the normal "digitalRead".
    This has no impact on the performance of the code as I have seen yet but will throw up an error if you do not have the library installed.

    Cheers
  8. llluis

    llluis Active Member Gold Contributor

    Joined:
    Mar 30, 2017
    Messages:
    164
    Location:
    Quebec
    Balance:
    1,630Coins
    Ratings:
    +103 / 1 / -0
    My Motion Simulator:
    6DOF
    Great idea. Did you have any progress on this? I'm thinking of trying this too for my 6DOF and eliminate the belts, etc.
    1x Teensy would read all 6 encoders and provide the output to SMC3.
  9. steamtrac

    steamtrac New Member Gold Contributor

    Joined:
    Sep 2, 2016
    Messages:
    20
    Location:
    Germany
    Balance:
    136Coins
    Ratings:
    +1 / 0 / -0
    Great approach. But one question: What is The cycle time of the Arduino? 5ms? Do you feel any lag when using the additional controller inbetween? Thanks!
  10. Alexey

    Alexey Well-Known Member

    Joined:
    Sep 23, 2014
    Messages:
    452
    Occupation:
    Electronics Technician
    Location:
    Adelaide, Australia
    Balance:
    8,061Coins
    Ratings:
    +620 / 2 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    The code works as is but there is far more to do in terms of calibration automation. Whilst the code can work on any length of travel each individual case needs a custom calibration routine to run the motors in one direction and hit the end stop, and then run the other way to find the other end stop to calibrate the range of travel. That part I have not done as I have extremely limited time to do anything these days.

    The base code is there, just needs finishing. It is available for anyone to modify as they see fit.

    I wouldn't know as it has not run on a motion sim. I doubt you could ever notice 5ms of delay. Even so I do not know what the cycle time of the code is but it is very small so I could hazard a guess of maybe 30 cycles of the processor for the loop. so that would be 1/16,000,000 x 30 = 1.8 micro seconds or thereabouts.
  11. Gustavo Massaneiro

    Gustavo Massaneiro New Member

    Joined:
    May 8, 2018
    Messages:
    14
    Location:
    Brazil
    Balance:
    78Coins
    Ratings:
    +6 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, Arduino, 4DOF, 6DOF
  12. Flymen

    Flymen Flymen Gold Contributor

    Joined:
    May 19, 2018
    Messages:
    336
    Location:
    Montreal, Canada
    Balance:
    2,423Coins
    Ratings:
    +191 / 2 / -0
    My Motion Simulator:
    DC motor, 6DOF
  13. wannabeaflyer2

    wannabeaflyer2 Well-Known Member

    Joined:
    Jun 12, 2015
    Messages:
    724
    Location:
    london uk
    Balance:
    8,299Coins
    Ratings:
    +953 / 7 / -0
    My Motion Simulator:
    2DOF, Arduino, Motion platform, 6DOF
    1. Hi @Flymen you aske dthe question at the right time , Thanos has just been in touch to say he's shipping my goodie bag of bits back to the UK for me so I can at last try to kickstart this phase of the project again , had some issue with getting the Barebones PC to communicate with the Sabertooths im using but hoping when the bits turn up i'll be able to start posting again ... project not dead in my eyes , just the ol guys been playing with Electric paragliders and flying so winter will see me back here with a vengenc :)
  14. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,935
    Location:
    London
    Balance:
    11,838Coins
    Ratings:
    +472 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    I am pretty sure the latest iot esp8266 has 2 processors and is compatible with arduino code

    So you could use one processor for counting pulses

    I suggest an optical sensor on each end to measure full travel and count the pulses to find the midpoint

    100 pulses per revolution should be enough resolution for a sim
  15. Flymen

    Flymen Flymen Gold Contributor

    Joined:
    May 19, 2018
    Messages:
    336
    Location:
    Montreal, Canada
    Balance:
    2,423Coins
    Ratings:
    +191 / 2 / -0
    My Motion Simulator:
    DC motor, 6DOF
    Hello Quebecois !
    Have you still a pot systeme on your 6DOF or now you have 6 encoders ?
    Thanks
  16. wannabeaflyer2

    wannabeaflyer2 Well-Known Member

    Joined:
    Jun 12, 2015
    Messages:
    724
    Location:
    london uk
    Balance:
    8,299Coins
    Ratings:
    +953 / 7 / -0
    My Motion Simulator:
    2DOF, Arduino, Motion platform, 6DOF
    Hi Guys this is not my post but thought id add that I have made some progress and the Thanos Encoder2pos interface is now working with my AMC128USB barebones test setup and alongside Ians BFF motion control Software im seeing what looks like the start of good option ...

    Still dragging my heals regarding simtool ( as its another thing I'd need to learn --getting older so things take a while to soak in LOL ) but will start posting update on my DIY actuator thread for anyone that's interested in thinking about this option ...what it does confirm is that Optical encoder option for feedback is now firmly in the DIY camp ..

    as I have 6 of these Encoders the plan will be to roll out the upgrade once im happy with the safety and testing on my spare actuator .

    Still tidying up my spare trail linear actuator but the system as it stands consists of

    DIY linear actuator
    1 x Optical Encoder
    1 x Encoder2pos Interface (Thanos)
    1 x Barebones AMC128USB Controller (Thanos)
    1 x Sabertooth 2X60 Motor Controller
    Software is currently Ians BFF 6DOF Motion driver ( limited Sim support for Flight and car simul0ation)
    Flight sim being FSX

    thanks to testing and setup trails using SMC3 and the Ardunio I will have that option in place as well once I get to grips with Simtools ( excellent support for Car simulation and Flight Simming )

    and last but not least the sabertooth /Kangeroo/simtools option is there lurking as well..

    Cheers Guys
    • Like Like x 1
    • Informative Informative x 1
  17. llluis

    llluis Active Member Gold Contributor

    Joined:
    Mar 30, 2017
    Messages:
    164
    Location:
    Quebec
    Balance:
    1,630Coins
    Ratings:
    +103 / 1 / -0
    My Motion Simulator:
    6DOF
    Hello! :)

    Life got in the way and I had to halt my build.
    But for now, I dropped the encoder idea and designed using the standard pots.
  18. SeatTime

    SeatTime Well-Known Member

    Joined:
    Dec 27, 2013
    Messages:
    2,573
    Occupation:
    Retired
    Location:
    Brisbane Australia
    Balance:
    28,370Coins
    Ratings:
    +2,844 / 39 / -0
    My Motion Simulator:
    AC motor, Motion platform
    Nothing against using Encoders, but standard pots are very 'KISS' and have worked OK for me for quite some time. Just don't use those blue Chinese rubbish ones which just fall apart - yes, it happened to me on my first sim...:rolleyes:. I used VISHAY wirewound ones in my 6DOF actuators which cost about $32AUD each - obviously they will wear over time, but mine are still going strong since may 2015.
    • Like Like x 2
  19. Gadget999

    Gadget999 Well-Known Member

    Joined:
    Dec 27, 2015
    Messages:
    1,935
    Location:
    London
    Balance:
    11,838Coins
    Ratings:
    +472 / 9 / -0
    My Motion Simulator:
    2DOF, DC motor, Arduino, 6DOF
    are they multi turn or do you use a reduction gear so one pot revolution = the full stroke of the actuator ?
  20. SeatTime

    SeatTime Well-Known Member

    Joined:
    Dec 27, 2013
    Messages:
    2,573
    Occupation:
    Retired
    Location:
    Brisbane Australia
    Balance:
    28,370Coins
    Ratings:
    +2,844 / 39 / -0
    My Motion Simulator:
    AC motor, Motion platform
    Multi turn.