I am building a robot arm that is actuated by a pneumatic cylinder. Extending and retracting the piston would increase and decrease the joint angle respectively. This is done using a 5/3 solenoid valve controlled by a relay switch. The actual joint angle is feedback using a potentiometer connected to analog A0 pin of an Arduino Uno.

I have a basic idea of how the whole mechanism would work to control position of the piston but have some queries and also on the use of Analog Comparator to serve as interrupt.

The components I am using are:

  1. Pneumatic Cylinder that would be fitted with speed reducing connectors to hopefully slow down the piston action enough to be controllable
  2. 5/3 Solenoid Valve
  3. Relay Module
  4. Potentiometer

Basic idea of how the system would function:

  • Potentiometer reading is mapped to joint angle range
  • User keys in target joint angle
  • If target joint angle < measured joint angle, switch on relay to power desired solenoid valve and extend the piston and the opposite when target joint angle > measured joint angle
  • If target joint angle = measured joint angle, switch off relays and solenoid valve would be in closed position, i.e.: no air input and piston stays in position


  1. Interrupt vs Polling

    • The control loop needs to know when the actual joint angle = target joint angle so as to switch off the relay and power down the solenoid valve. This requires an interrupt signal when the potentiometer reading reaches a certain value correct?
    • Polling of the potentiometer using analogRead() may miss a reading? Or would polling simply be the more straightforward way to get joint angle feedback?
  2. Analog Comparator

    • If interrupt is the way to go, this would mean needing to use the in-built analog comparator on Uno. I read up on it and the idea is to put a reference voltage at D7 of Uno, while the potentiometer values are input at D6. When the input voltage passes the reference voltage, an interrupt (either falling or rising edge) would occur.
    • But this would mean that there can only be one fixed reference voltage right? Or is there a means to have variable reference voltage sent in to D7 according to user input desired values?
    • And the Uno only has these two pins for analog comparator, it would not be able to support a two-joint robot arm with angles measured by two different potentiometers correct?

Or are there smarter ways to achieve control of the piston position?

  • $\begingroup$ Is it possible to use a proportional valve rather than a binary solenoid? $\endgroup$
    – tsbertalan
    Commented Jul 26, 2018 at 16:27
  • $\begingroup$ Definitely, but it is much more expensive than a binary solenoid $\endgroup$
    – Citrusying
    Commented Jul 26, 2018 at 21:37

1 Answer 1


Answering Your questions:

    • It doesn't require any interrupt signal. You can just check if measured joint angle is equal to the desired one.
    • I have no idea why analogRead() would "miss" a reading. If the software will be properly written (no redundant code inside interrupts, that might cause the software to hang on the interrupt), then analogRead() should work as expected.
  1. As for analog comparator answers, let's check out the ATMega328P documentation.

    • ATMega328P supports only one analog comparator, so only one reference voltage should be supplied. Therefore, using more potentiometers with this method will require usage of external comparators.

    • Morever, analog comparator output will only give You the information if measured voltage is "higher or equal" or "lower" than the voltage on the other input - there is no "equal" signal, so Your three step regulator would be always rocking around the desired point.

Taking everything into consideration, software measurement of the potentiometer voltage for the negative feedback of the control loop will be best for Your application.

One thing for You to remember: arm, relays, valves, pistons etc. have delays and inertia, as these are moving physical objects. Moreover, voltage measurement on the potentiometer always have some uncertanities and is never super steady, as we'd like to. Therefore, your robotic arm with Yours regulation algorithm will have a very big problem with going exactly to the point, where potentiometer voltage is correct. Probably it will oscillate around the desired angle. Adding hysteresis to Your control algorithm should solve that problem - it will get to the angle near desired one without oscillation, if the hysteresis will be big enough. With that, You'll get a double-setpoint controller.

However, please consider usage of the PID algorithm. For Your hardware configuration it will function at rather low frequencies (as relays and valves need some time to be open), but properly tuned it should give You satisfying results, reaching desired joint angle fast and with small regulation error.

  • $\begingroup$ I did start off with PID control loop but ran into issues along the way. The target and reference values would be the joint angles mapped from potentiometer, so error would also be in terms of joint angle. I cannot directly feedback the error to the relay because the relay is simply ON/OFF state. Thought of using the error to control the time duration for which the relay is switched ON based on the time for 1 full stroke. However, this would be problem as the time is dependent on the gas pressure available among other factors. Are there other means for PID control? $\endgroup$
    – Citrusying
    Commented Jul 19, 2018 at 11:27
  • 1
    $\begingroup$ As I understood, You have pressure valve with common side connected to some pressure tank and two outputs connected to the piston. It is driven by the relay module. With that configuration you can utilize PID controller, which with constant period turns on and off valves. Duty on every valve is based on the PID output. $\endgroup$
    – Szczepan
    Commented Aug 3, 2018 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.