My project is to use an Arduino to control two solenoid valves with PWM and receive an input signal from a sensor as feedback.

enter image description here

The valves direct the flow of water which cause a hydraulic actuator to move which is detected by an LVDT sensor.

What I want my program to do is to allow me to set a desired displacement as a goal which causes the Arduino to dynamically change the duty cycle of the pwm signal based off of the feedback input the Arduino receives. I am going to implement a PID to control it.

The circuit consist of the Arduino sending PWM signals to two logic level NPN mosfets to control the solenoids that are powered by 2 external 12V sources.

enter image description here

enter image description here

What I specifically need help with is how to write the part of the program that will let me produce 2 PWM signals that will allow me to change the frequency of the pwm waves so that the solenoids have enough time to switch and then also the ability to set the duty cycle.

I am a total novice programmer and its my first time working with electronics. I'm just hoping someone can point me in the right direction.

  • What sort of frequency do you need to run the solenoids at? If it's on the order of 10Hz, 1Hz, or slower, you might consider implementing a software PWM rather than use hardware PWM.
    – Dave X
    Sep 29 '21 at 0:45

If you only need two PWM pins, I suggest using hardware PWM with Timer 1. The Timer 1 library makes the process quite easy. It supports frequencies from 0.12 Hz up to a few MHz, although the resolution degrades above 7.8 kHz.

Compared to an interrupt-based solution, hardware PWM has less jitter and it does not consume CPU cycles. The drawback is that you will be limited to 2 channels operating at the same frequency, but this doesn't seem to be an issue for your project.


You can try to use my AVR_Slow_PWM Library, which can provide these following features and generate 2 independent PWM signals to any GPIO pin. Certainly only if your hardware design can correctly use PWM signals.

This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., using AVR core to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at 500Hz, which is still suitable for many real-life applications

  • Just out of interest: are you using digitalWrite() for your software PWM?
    – Sim Son
    Sep 28 '21 at 9:11
  • Yes. digitalWrite() is used whenever a change is necessary.
    – khoih-prog
    Sep 29 '21 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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