For a (crazy) upcoming school project I am converting a piano to be a computer-controlled player piano. I am currently planning on using solenoids mounted under the end of the keys (action side obviously, like Yamaha's DiskClavier system as well as the PianoDisc system).

I am planning on using an Arduino to take MIDI signals and drive all of the solenoids. I need PWM on the solenoids so that I can control the velocity at which the solenoids hit the keys, thereby determining the volume. The problem is, its no easy task to control, using PWM, 88 solenoids using an Arduino.

I was think I could use a generic PWM generator to generate the signals, and there are 16-channel servo PWM generator boards out there that are VERY cheap. However, servos require a very specific type of signal that is rather different that generic PWM which I need here. Does anyone know if these will work to generate generic PWM? (link: http://www.ebay.com/itm/PCA9685-16-Channel-12-bit-PWM-Servo-motor-Driver-I2C-Module-For-Arduino-Robot-/272557014281?hash=item3f75a9fd09:g:6SIAAOSwax5Yozsi)

Once I get a PWM signal, can I just use a MOSFET and diode (for kickback-voltage protection) to drive the solenoids directly?

Anything I'm completely missing here?

Any help and guidance is greatly appreciated.

P.S. I know I'm a little bit crazy trying to do this.

  • 1
    \$\begingroup\$ (I like crazy. It's part of how one learns. Jumping into the deep end has risks, but it has lessons, too.) But first, you need to work out exactly how you are going to drive the keys. You mentioned PWM, but will it achieve what you want? Can it be done in simpler fashion without losing sight of the goals? What other methods might you also try? If you came here with all this worked out, I think the rest might be easier to address. But you really need to work this out, first. And make sure the idea works equally well from the lowest A to the highest C. Keys are weighted differently. \$\endgroup\$
    – jonk
    Mar 24, 2017 at 2:16
  • \$\begingroup\$ Set aside the Arduino for now and ask your self what king of power will 88 solenoids require. Sure, you will not activate all at one time, but activating 10 simultaneously is realistic. Also, is the jerky nature and sudden current draw of a solenoid too much of a draw back. It may be easier to use 88 inexpensive DC toy motors to gently pull on the keys. But even this will require interface hardware between the Atmel processor in the Arduino and the motors. In steps servo motors. Way more expensive than toy motors, but directly controllable from an Arduino. And now you can use PWM. \$\endgroup\$
    – st2000
    Mar 24, 2017 at 3:27
  • \$\begingroup\$ This project sounds expensive! Considering the response rates of small solenoids that are powerful enough to actuate keys appropriately, you might be able to get away with a set of eleven cascaded 74HC595 shift registers to provide the pulses going into the MOSFET gates. You'd have to clock them pretty fast though (several megahertz probably). The output enable (EN) pins can simply be tied high all the time and just use DATA and SCLK to clock out the PWM bits and finally pulse RCLK on and off once every 88 bits have been sent. You'd probably need more CPU power than an Arduino can provide. \$\endgroup\$
    – user98663
    Mar 24, 2017 at 8:47
  • \$\begingroup\$ @Wossname If I'm not mistaken, that approach will only give me PWM control over the entire setup, and not individual solenoid PWM signals. Or am I mistaken? I specifically need to be able to control the velocity of individual solenoids, and not all of them at once. \$\endgroup\$ Mar 26, 2017 at 0:43
  • \$\begingroup\$ @st2000 I thought about servos for a while, but the problem is that servos fast enough and that have enough torque for this application are WAY expensive compared to comparable solenoids. I have thought about the power requirements of this project, and it is something of a problem. The solenoids that would work for this would draw around 1A, which means that if all of them were fired it would be almost 100A at 12V which isn't completely insane (although still pretty insane, I'll be fair). I would have software limits that wouldn't allow all the solenoids to fire at once as well. \$\endgroup\$ Mar 26, 2017 at 0:45

1 Answer 1


Forget craziness - good for you, investigating and experimenting is a great way to learn.

The NXP PCA9685 module you've identified will drive FETs, as you describe. Put a 1 K series resistor between each PCA9685 output and its FET gate. This limits the current to/from the gate capacitance during PWM output switching to 5 mA max, otherwise the PWM output is driving into a short-circuit on its rising edge.

I would also allow for, or put in, a 10 K pull-down to GND on each PWM output. The PCA9685 data sheet states that the outputs will go low during reset of the IC. On power-up, you don't want dozens of solenoids clicking because its not immediate enough or something else unforeseen. This is purely a precaution, allowing you to put a pull-down on the PCA9685 /OE pin and have the Arduino drive it logic high once the supply has stabilised and the circuit settled. Shouldn't be needed but better to plan it in and not fit the parts in your experimental lash-up.

  • \$\begingroup\$ Thanks for this! I didn't realize that the Adafruit "Servo PWM" boards are using the NXP PCA9685, which is simply a standard PWM controller designed for LED control applications! Stupid me, I should have done this research. \$\endgroup\$ Mar 26, 2017 at 0:41
  • \$\begingroup\$ @willem.hill, nothing stupid - this is a good choice of PWM module. You can drive what you like off it, the LED driving was just the manufacturer's intended market. Look at FET arrays in ICs and you can get your component count down there, too. \$\endgroup\$
    – TonyM
    Mar 26, 2017 at 9:02

Your Answer

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

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