Arduino and hydraulics/oleodynamics proportional valve

Hi to all,

I would like to receive suggestions on how to control proportional valves with Arduino, if this is possible.
I attached to this topic, a photo about my current system: it has two proportional valves and one ON/OFF valve and I need to use it to control an hydraulics motor.
I also attached the datasheet for the proportional valve.

The proportional valves are V=12VDC and 26W while the ON/OFF valve is V=12VDC, R = 3.7 Ohm, I = 1.80A.
Each valve has three pins but I dont have the pinout so I don’t know how to use them.

For the ON/OFF valve, I was thinking to use a solid state relay and I think it should be easy to control it with Arduino.

The problem is that I don’t know how to control the proportional valve.
What kind of signal do I have to use in order to control them?
Should I use a PWM signal by changing the voltage output?
For example, do I have to assume that at 12VDC and 2.1A, the proportional valve is fully opened and that, for example, at 10VDC and 2.6A it is partially opened?

I’m sorry if these questions are too stupid, but I’m really new to this kind of topics.

Thank you for your help! :slight_smile:

Googling on PWM to current controllers will show some circuits.

thank you for your suggestion.

I already googled it, but I didn’t understand how to set the PWM to 120Hz and also I don’t understand the pinout for my valves.

Each valve has three contacts and one of them has the earth label on it (why earth if it is a DC system?)
Don’t I have to find the positive contact?

I attached a photo to show you the contacts.

The on off valves will be a coil with possibly a diode connected across it, measuring the resistance across it with a multimeter set to diode test position should give you the polarity.
Assuming they are for rated DC of course.
An AC coil will not have the diode.

Earth is likely the body earth only.

120 HZ , i do not understand that.

The idea is to use the arduino to output a PWM signal and convert that to current.
By varying the PWM signal the current is thus varied.

There is a pwm library to help there.

If you read the datasheet attached to my first post, it says that the PWM for the vale should be set at 120Hz.

So, do I have to set the PWM frequency at 120Hz?
Should I use a timer for this?

OK i understand.
It means the repetition rate is 120 HZ with the mark space ratio varied , the servo library is probably the one to use.

Some pneumatic valves work like this, i am unfamiliar with some of the detail of hydraulics though, does the data sheet give any application information or suggested circuits,

This recent thread may help , assuming there is no operational difference between a pneumatic and hydraulic valve.

The servo library has a function writeMicroseconds().

That sets the width of the pulse, using a loop with delayMicroseconds() could set the period.

Crude method but a simple implementation.

You could use timers and digitalWrite() also.

Not sure what your programming skills are, mine are not so good.

What i am not sure about though is what the maximum allowed value for writeMicroseconds() is.

a simple FET and a diode is enough.
connect the coil to the FET and the Gate to the arduino, (dont mind the PWM speed for now.
if you set the PWM (AnalogWrite) to 128 only half the time the coil is active so the valve will be open half.

Thank you, guys!

I did it, but I can't understand if it works!

I mean, if I set PWM 80%, then I can hear a very small "tick" coming from the valve.. but nothing else.
If I set PWM 50%, it seems nothing happens to the valve.
For sure, I can see that the current comsumption changes from 0.5A to 2.1A when PWM is at 100%.

How can I understand if the valve is correctly working?

At this moment, it is not connected to my hydraulics system since I'm testing the valve on my benchwork.

I think the pwm statement uses a frequency of about 800 HZ which is much higher than required.

The servo library is 50 HZ but has a better chance of operating the valve.


My valve is designed for an analogue voltage yours is for pwm although i fail to see the mechanical difference.
You might try a capacitive filter across the output and see if that improves things.

It may be the core structure is different laminated/solid though, someone in the other thread mentioned this.

Some liquid valves require a pressure to be applied in order to actuate the 'valve' itself... the PWM control simply open/closes the bypass which allows the valve to 'move' to the required aperture when the pressure is applied.

In some cases, the flow of liquid provides cooling, so check the spec for continuous current ratings vs temperature.


If you edit the servo.h file and replace these two lines

#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds

with these

#define MAX_PULSE_WIDTH 8300 // the longest pulse sent to a servo
#define REFRESH_INTERVAL 8300 // minumim time to refresh servos in microseconds

It will do what you want, I have tried it on a scope.

Tomorrow, I will test the valves on my real oleodynamics system.

At the moment, I was not using the servo library, since I nerver used it before.
Following your suggestion, I can’t understand how to use the library, since I’ve read it is only for servo motors.
You can only set degree values, if I well understood by the servo library tutorial.

For example, if I use a potentiometer and then I use this code:

void loop() 
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 
  val = map(val, 0, 1023, 0, 179);     // scale it to use it with the servo (value between 0 and 180) 
  myservo.write(val);                  // sets the servo position according to the scaled value 
  delay(15);                           // waits for the servo to get there 


will I be able to control my proportional valve opening?

In the servo library is a sketch called sweep.

Compile and run it and it will go from 0 to 100% and back again.

Modify the lines i suggested and if you have an analogue meter you should see it wag betwen 0 and 100%.

It should be very easy to modify the code in sweep to do what you want.

Any specific problems just ask.

I did something very similar many years ago using a PIC.

There is another example called knob which does exactly what you are doing.

Yes, the code I posted before comes from the knob example.

But, if I want to make the valve go from close-to-fully_open, what set of values should I use?

 val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 100);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value

From 0 to 100?


what is the meaning of this code?

#define MAX_PULSE_WIDTH      8300     // the longest pulse sent to a servo
#define REFRESH_INTERVAL    8300     // minumim time to refresh servos in microseconds

why did you set 8300?

The servo library is a general PWM generator with a specific set of values corresponding to a generally accepted standard for servos of 20 mS per frame.

8300 uS =8.3 mS which is the period of a 120 Hz PWM signal.

as far as range goes ill have a look when i get home.


A position of 180 degrees appears to correspond to 100% PWM.

The statement myservo.write() should have a value of 0 to 180 corresponding to 0 to 100% PWM.

The statement myservo.writeMicroseconds() should have a value of 0 to 8300 corresponding to 0 to 100% PWM.


If you have not spotted this already, the statement myservo.write() only has to be made once.
It is only required to state it again if you wish to change the value.

The servo library will continue to output the last remembered value.