Controlling the Adafruit PWM Driver from Java

This article will show how to control the Adafruit 16CH 12 bit PWM driver from a Raspberry PI using Java.

  1. First step is to configure your Raspberry PI for I2C.
  2. Next step is to set up PI4J.
  3. Next is to download the tiny little library for accessing the PWM driver I just made (and/or the source).


This is the raspberry hooked up to various things, one of them being the PWM driver. The easiest way to test the library is to hook up a servo to channel 0 and run the jar. The test program also accepts a servo on channel 1, and motors (via H-bridges) on channel 2 and 3. Do not, under any circumstance, run the test program with servos on channel 2 and 3, unless you edit it first.

Here is how to run the test program:

sudo java -classpath .:classes:/opt/pi4j/lib/*:./pwm.jar se.hirt.pi.adafruit.pwm.test.PWMTest

You should see something like this:

And this is how to use it:

First construct a PWMDevice:

PWMDevice device = new PWMDevice();

If you’re using the default address (0x40) on I2C bus 1, you can safely use the default constructor. Next select the PWM frequency to use. 50 Hz is, for example, good for RC servo control:


Next select the channel for which you want to alter the PWM signal, for example channel 0:

PWMChannel servo0 = device.getChannel(0);

Setting the PWM signal is done with the setPWM(int on, int off) channel method. We have 12 bit fidelity with which to choose when to go from low to high, and vice versa. That gives us a valid number from 0 to 4095, with 0 meaning in the beginning of the pulse, and 4095 meaning the end. So, for most servos, the internetz say that a 1ms pulse means minimum servo travel, and a 2ms pulse means maximum servo travel. 1.5 ms is centered. 50Hz means every pulse is about 20ms. 1/20 of 4096 means that minimum servo travel should be about 205. Max travel should be around 410. Of course, your mileage may vary, and servos can usually travel a bit further than this. Anyways, this would be setting min:

servo0.setPWM(0, 205);

See the test program in the source jar for more examples. Have fun!

Conclusion and Tips

  • The Adafruit 16CH 12 bit PWM driver is a wonderful little breakout board for controlling servos and motors (via an H-bridge).
  • You can use 6V for driving the servos (V+) – just make sure that the servos can handle it.
  • Servos that are specified to handle 6V are usually faster/stronger when running on 6V.
  • I am using a Polulu voltage regulator for driving the Raspberry PI off of a 3S LiPo-battery. I am using a separate BEC for servos/motors.

9 Responses to "Controlling the Adafruit PWM Driver from Java"

  1. Zachary says:

    Nice! I will definitely use this for my quadcopter project!! Thanks!

  2. David says:

    This was just what I needed. The adafruit stuff is all in python and all of my other code is in Java. Great stuff! Thanks again!

  3. Marcus says:

    No problem! Glad to help! πŸ™‚

  4. Dave says:

    Very helpful.
    Can you tell me how to set a Motor to run backwards?
    (the java equivalent to the python )

  5. Marcus says:

    That would depend on your motor controller. Some H-bridge controllers have a separate pin for controlling direction (you would use a separate GPIO-port for changing direction), some more advanced controllers can be configured to have centered (1.5ms) be stopped, and then move from full ahead in one direction, via stopped, to full ahead in the other direction.

    In my lovely robot (Coff-E, since he runs on Java) I use both variants.

  6. Peter says:

    This needs a maven repo

  7. Marcus says:

    We will start publishing builds of Robo4J when we get closer to a release. πŸ™‚ See!

  8. Robert says:

    Sweet. Thanks for the excellent work you’ve done. Very useful and very transparent.

Leave a Reply

Your email address will not be published.