출처 : Raspberry Pi SPI and I2C Tutorial
Use the Adafruit PCA9685 with a Raspberry PI, in Java Raspberry PI to drive up to 16 servos
JavaScript Robotics: Servo - PCA9685
I2C on Pi
i2c device 활성화
# /etc/modules: kernel modules to load at boot time. # # This file contains the names of kernel modules that should be loaded # at boot time, one per line. Lines beginning with "#" are ignored. i2c-bcm2708 i2c-dev
gpio commands
gpio version: 2.32
Copyright (c) 2012-2015 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
Raspberry Pi Details:
Type: Model B, Revision: 03, Memory: 512MB, Maker: Egoman
* Device tree is enabled.
* This Raspberry Pi supports user-level GPIO access.
-> See the man-page for more details
-> ie. export WIRINGPI_GPIOMEM=1
+-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT0 | 1 | 3 || 4 | | | 5V | | |
| 3 | 9 | SCL.1 | ALT0 | 1 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 1 | 7 || 8 | 1 | ALT0 | TxD | 15 | 14 |
| | | 0v | | | 9 || 10 | 1 | ALT0 | RxD | 16 | 15 |
| 17 | 0 | GPIO. 0 | IN | 0 | 11 || 12 | 0 | IN | GPIO. 1 | 1 | 18 |
| 27 | 2 | GPIO. 2 | IN | 0 | 13 || 14 | | | 0v | | |
| 22 | 3 | GPIO. 3 | IN | 0 | 15 || 16 | 0 | IN | GPIO. 4 | 4 | 23 |
| | | 3.3v | | | 17 || 18 | 0 | IN | GPIO. 5 | 5 | 24 |
| 10 | 12 | MOSI | ALT0 | 0 | 19 || 20 | | | 0v | | |
| 9 | 13 | MISO | ALT0 | 0 | 21 || 22 | 0 | IN | GPIO. 6 | 6 | 25 |
| 11 | 14 | SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT | CE0 | 10 | 8 |
| | | 0v | | | 25 || 26 | 1 | OUT | CE1 | 11 | 7 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| 28 | 17 | GPIO.17 | IN | 0 | 51 || 52 | 0 | IN | GPIO.18 | 18 | 29 |
| 30 | 19 | GPIO.19 | IN | 0 | 53 || 54 | 0 | IN | GPIO.20 | 20 | 31 |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+-Model B2-+---+------+---------+-----+-----+
detect I2C chips
출처 : i2cdetect(8): detect I2C chips - Linux man page
/dev/i2c-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 -- -- -- -- -- -- --
배선
PCA9685Gpio.java
출처 : wyliodrin-server-nodejs/libs/raspberrypi/java/pi4j/examples/PCA9685GpioExample.java
package com.bluexmas.arm; import java.io.IOException; /** * sudo java -cp .:pi4j-core.jar:pi4j-device.jar:pi4j-gpio-extension.jar:pi4j-service.jar com.bluexmas.arm.PCA9685Gpio */ import java.math.BigDecimal; import com.pi4j.gpio.extension.pca.PCA9685GpioProvider; import com.pi4j.gpio.extension.pca.PCA9685Pin; import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinPwmOutput; import com.pi4j.io.gpio.Pin; import com.pi4j.io.i2c.I2CBus; import com.pi4j.io.i2c.I2CFactory; import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException; public class PCA9685Gpio { private static final int SERVO_DURATION_MIN = 650; private static final int SERVO_DURATION_NEUTRAL = 1500; private static final int SERVO_DURATION_MAX = 2100; private static PCA9685Gpio instance = null; private PCA9685GpioProvider gpioProvider = null; private PCA9685Gpio() throws IOException, UnsupportedBusNumberException { System.out.println("<--Pi4J--> PCA9685 PWM Example ... started."); // This would theoretically lead into a resolution of 5 microseconds per // step: // 4096 Steps (12 Bit) // T = 4096 * 0.000005s = 0.02048s // f = 1 / T = 48.828125 BigDecimal frequency = new BigDecimal("48.828"); // Correction factor: actualFreq / targetFreq // e.g. measured actual frequency is: 51.69 Hz // Calculate correction factor: 51.65 / 48.828 = 1.0578 // --> To measure actual frequency set frequency without correction // factor(or set to 1) BigDecimal frequencyCorrectionFactor = new BigDecimal("1.0578"); // Create custom PCA9685 GPIO provider I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1); gpioProvider = new PCA9685GpioProvider(bus, 0x40, frequency, frequencyCorrectionFactor); // Define outputs in use for this example GpioPinPwmOutput[] myOutputs = provisionPwmOutputs(gpioProvider); // Reset outputs gpioProvider.reset(); } public static PCA9685Gpio getInstance() throws IOException, UnsupportedBusNumberException { if (instance==null) instance = new PCA9685Gpio(); return instance; } public void setPwm(Pin pin, int duration) { gpioProvider.setPwm(pin, duration); } public void shutdown() { gpioProvider.shutdown(); } private static GpioPinPwmOutput[] provisionPwmOutputs(final PCA9685GpioProvider gpioProvider) { GpioController gpio = GpioFactory.getInstance(); GpioPinPwmOutput myOutputs[] = { gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_00, "Pulse 00"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_01, "Pulse 01"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_02, "Pulse 02"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_03, "Pulse 03"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_04, "Pulse 04"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_05, "Pulse 05"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_06, "Pulse 06"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_07, "Pulse 07"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_08, "Pulse 08"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_09, "Pulse 09"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_10, "Always ON"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_11, "Always OFF"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_12, "Servo pulse MIN"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_13, "Servo pulse NEUTRAL"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_14, "Servo pulse MAX"), gpio.provisionPwmOutputPin(gpioProvider, PCA9685Pin.PWM_15, "not used") }; return myOutputs; } public static void main(String[] args) throws Exception { PCA9685Gpio test = PCA9685Gpio.getInstance(); test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MIN); // Set 1.5ms pulse (R/C Servo neutral position) Thread.sleep(2000); test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_NEUTRAL); // Set 2.1ms pulse (R/C Servo maximum position) Thread.sleep(2000); test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MAX); Thread.sleep(2000); test.setPwm(PCA9685Pin.PWM_00, SERVO_DURATION_MIN); Thread.sleep(2000); test.shutdown(); } }
실행
<--Pi4J--> PCA9685 PWM Example ... started.