I2C.SPI
The Servo Driver we are talking about here is the Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface - PCA9685.
nano
, vi
, gedit
, ...), as root (sudo
).
/etc/modules
i2c-bcm2708 i2c-devSave your modifications, if you have done any.
Prompt> sudo apt-get install python-smbus Prompt> sudo apt-get install i2c-tools
/etc/modprobe.d/raspi-blacklist.conf
, comment the two lines it contents:
blacklist spi-bcm2708 blacklist i2c-bcm2708
# blacklist spi-bcm2708 # blacklist i2c-bcm2708Save your modifications, if you have done any.
i2cdetect
utility, which will will use to know the address of the servo driver:
Prompt> sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- --As seen above, the I2C addresses range from 0x03 to 0x77 (binary 0000011 to 1110111). This way, several boards can be used simultaneously from the RasPI, as long as their I2C addresses are different, even if the GPIO interface pins are connected to several different boards.
Prompt> sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- 19 -- -- -- -- 1e -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- 77where, in addition to the above,
0x19
would be the magnetometer address (LSM303)0x1e
would be the accelerometer address (LSM303)0x77
would be the BMP180 address
|
![]() |
![]() |
![]() The Raspberry PI, connected to a PCA9685, with 2 servos. |
i2cdetect
utility.
Prompt> sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- --We will use the
0x40
address to reach the PCA9685.
PCA9685
. Check it out in the repository. We are going to comment only on the main
method of this class, which is a basic example. It assumes that 2 servos are connected to the PCA9685, on the 15 and 14 slots.... public static void main(String[] args) { PCA9685 servoBoard = new PCA9685(); // 0x40 is the default address servoBoard.setPWMFreq(60); // Set frequency to 60 Hz int servoMin = 150; // Min pulse length out of 4096 int servoMax = 600; // Max pulse length out of 4096 final int CONTINUOUS_SERVO_CHANNEL = 14; final int STANDARD_SERVO_CHANNEL = 15; for (int i=0; i<10; i++) { System.out.println("i=" + i); servoBoard.setPWM(STANDARD_SERVO_CHANNEL, 0, servoMin); servoBoard.setPWM(CONTINUOUS_SERVO_CHANNEL, 0, servoMin); waitfor(1000); servoBoard.setPWM(STANDARD_SERVO_CHANNEL, 0, servoMax); servoBoard.setPWM(CONTINUOUS_SERVO_CHANNEL, 0, servoMax); waitfor(1000); } servoBoard.setPWM(CONTINUOUS_SERVO_CHANNEL, 0, 0); // Stop the continuous one System.out.println("Done with the demo."); } ...This code loops 10 times and makes the servos go from a value of 150 to a value of 600, and vice versa. It waits for 1000 milliseconds between each message to the servos.
int
variables, CONTINUOUS_SERVO_CHANNEL
and STANDARD_SERVO_CHANNEL
.
minServo
is 150.
maxServo
is 600.
TickTime = 1 / (freq * 4096)
.PulseTime = TickTime * nbTicks
.Pulse Width in ms | Nb Ticks |
---|---|
1 | 246 |
1.5 | 369 |
2 | 492 |
$I2C.SPI> ../gradlew clean shadowJarYou can run the code from a script named
servo
:
#!/bin/bash CP=./build/libs/I2C.SPI-1.0-all.jar sudo java -cp $CP i2c.servo.pwm.PCA9685
Prompt> ./servoAnd here is the result
Prompt> ./servo Connected to bus. OK. Connected to device. OK. Setting PWM frequency to 60 Hz Estimated pre-scale: 100.72526 Final pre-scale: 101.0 i=0 i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 Done with the demo Prompt>The console output |
For the Standard Servo | Between 122 & 615 ticks |
For the Continuous Servo | Between 340 & 410 ticks, stop at 375 |
i2c.samples.DemoContinuous
and i2c.samples.DemoStandard
.