BPI-M2 Berry - I2C 이용 PCA9685 제어

OS/Banana Pi /BPI-Bit 2018.01.01 13:31 Posted by 파란크리스마스

출처 : Maker Projects: Banana Pi I2C Devices
BPI-M2,use wiringPi I2C to read mpu6050 - Banana Pi BPI-M2 / Linux - banana pi single board computer official forum SinoVoip BPI team
node.js - johntreacy/adafruit-pca9685
adafruit/Adafruit_Python_PCA9685: Python code to use the PCA9685 PWM servo/LED controller with a Raspberry Pi or BeagleBone black.

BPI-M2 Berry GPIO Pin define

출처 : BPI-M2 Ultra GPIO Pin define · banana pi BPI-M2 Ultra/Berry allwinner R40/V40 SBC

GPIO Pin Name Default Function Function2:GPIO Function3
CON1-P01 VCC-3V3
CON1-P02 DCIN
CON1-P03 TWI2-SDA PB21 PWM5
CON1-P04 DCIN
CON1-P05 TWI2-SCK PB20 PWM4
CON1-P06 GND
CON1-P07 PB3 PB3 PWM1
CON1-P08 UART2-TX PI18 SPI1_MOSI
CON1-P09 GND
CON1-P10 UART2-RX PI19 SPI1_MISO
CON1-P11 UART7-TX PI20 PWM2
CON1-P12 UART2-CTS PI17 SPI1_CLK
CON1-P13 UART7-RX PI21 PWM3
CON1-P14 GND
CON1-P15 PH25 PH25 CSI1-FIELD
CON1-P16 UART2-RTS PI16 SPI1_CS0
CON1-P17 VCC-3V3
CON1-P18 PH26 PH26 CSI1-HSYNC
CON1-P19 SPI0_MOSI PC0
CON1-P20 GND
CON1-P21 SPI0_MISO PC1
CON1-P22 PH27 PH27 CSI1-VSYNC
CON1-P23 SPI0_CLK PC2
CON1-P24 SPI0_CS PC23
CON1-P25 GND
CON1-P26 PH24 PH24 CSI1-PCLK
CON1-P27 TWI3-SDA PI1
CON1-P28 TWI3-SCK PI0
CON1-P29 PH0 PH0 CSI1-D0
CON1-P30 GND
CON1-P31 PH1 PH1 CSI1-D1
CON1-P32 PD20 PD20 CSI1-MCLK
CON1-P33 PH2 PH2 CSI1-D2
CON1-P34 GND
CON1-P35 PH3 PH3 CSI1-D3
CON1-P36 UART5-RX PH7 CSI1-D7
CON1-P37 UART4-TX PH4 CSI1-D4
CON1-P38 UART5-TX PH6 CSI1-D6
CON1-P39 GND
CON1-P40 UART4-RX PH5 CSI1-D5

I2C 목록 조회 - i2cdetect -l

$ i2cdetect -l
i2c-0   i2c             twi0                                    I2C adapter
i2c-1   i2c             twi1                                    I2C adapter
i2c-2   i2c             twi2                                    I2C adapter
i2c-4   i2c             twi4                                    I2C adapter

I2C 주소 확인 - i2cdetect -y

$ i2cdetect -y 2
     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: -- -- -- -- -- -- -- --                         

gpio readall

 +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |  53 |   8 |   SDA.1 | ALT5 | 0 |  3 || 4  |   |      | 5v      |     |     |
func:sunxi_get_pin_mode pin:53,  bank:1 index:21 phyaddr:0x1c2082c
read reg val: 0x22222233 offset:20  return: 0
read reg val: 0x22222233 offset:20  return: 2
func:sunxi_digitalRead pin:53,bank:1 index:21 phyaddr:0x1c20834
***** read reg val: 0x0,bank:1,index:21,line:850
 |  52 |   9 |   SCL.1 | ALT5 | 0 |  5 || 6  |   |      | 0v      |     |     |
func:sunxi_get_pin_mode pin:52,  bank:1 index:20 phyaddr:0x1c2082c
read reg val: 0x22222233 offset:16  return: 0
read reg val: 0x22222233 offset:16  return: 2
func:sunxi_digitalRead pin:52,bank:1 index:20 phyaddr:0x1c20834
***** read reg val: 0x0,bank:1,index:20,line:850
| 257 |  30 |   SDA.0  | ALT3 | 0 | 27
func:sunxi_get_pin_mode pin:257,  bank:8 index:1 phyaddr:0x1c20920
read reg val: 0x77703377 offset:4  return: 0
read reg val: 0x77703377 offset:4  return: 7
func:sunxi_digitalRead pin:257,bank:8 index:1 phyaddr:0x1c20930
***** read reg val: 0x0,bank:8,index:1,line:850
                                       || 28 | 0 | ALT3 | SCL.0   | 31  | 256 |
func:sunxi_digitalRead pin:256,bank:8 index:0 phyaddr:0x1c20930
***** read reg val: 0x0,bank:8,index:0,line:850
func:sunxi_get_pin_mode pin:256,  bank:8 index:0 phyaddr:0x1c20920
read reg val: 0x77703377 offset:0  return: 0
read reg val: 0x77703377 offset:0  return: 7

BPI-M2 Berry - I2C 이용 PCA9685 제어 소스 - PCA9685Gpio.java

import java.io.IOException;
/**
 * $ sudo java -cp .:pi4j/* 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.BPIM2BerryGpioProvider;
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 {
	
	public static final int SERVO_DURATION_MIN = 600;
	public static final int SERVO_DURATION_NEUTRAL = 1500;
	public static final int SERVO_DURATION_MAX = 2400;
	
	private static PCA9685Gpio instance = null;
	
	private PCA9685GpioProvider gpioProvider = null;
	
	// sudo java -cp .:pi4j-core.jar:pi4j-gpio-extension.jar PCA9685Gpio
	
	private PCA9685Gpio() throws IOException, UnsupportedBusNumberException {		
		
		//GpioFactory.setDefaultProvider(new BPIM2PGpioProvider());
		//GpioFactory.setDefaultProvider(new NanoPiNEOAirGpioProvider());
		GpioFactory.setDefaultProvider(new BPIM2BerryGpioProvider());
		
		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_2);
		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_01, SERVO_DURATION_NEUTRAL);
		Thread.sleep(200);
		
		for (int i=SERVO_DURATION_MIN; i<=SERVO_DURATION_MAX; i+=30) {
			test.setPwm(PCA9685Pin.PWM_00, i);
			Thread.sleep(200);
		}
		
		for (int i=SERVO_DURATION_MAX; i>=(int)(SERVO_DURATION_MIN+(SERVO_DURATION_MAX-SERVO_DURATION_MIN)/2); i-=30) {
			test.setPwm(PCA9685Pin.PWM_00, i);
			Thread.sleep(200);
		}
				
		for (int i=SERVO_DURATION_MIN; i<=SERVO_DURATION_MAX; i+=30) {
			test.setPwm(PCA9685Pin.PWM_01, i);
			Thread.sleep(200);
		}
		
		for (int i=SERVO_DURATION_MAX-200; i>=(int)(SERVO_DURATION_MIN+(SERVO_DURATION_MAX-SERVO_DURATION_MIN)/2); i-=30) {
			test.setPwm(PCA9685Pin.PWM_01, i);
			Thread.sleep(200);
		}
		
		test.shutdown();

	}
	
}

컴파일

$ javac -cp .:pi4j/* -d . PCA9685Gpio.java

실행

$ sudo java -cp .:pi4j/* PCA9685Gpio

실행 영상




 

티스토리 툴바