1 / 37

임베디드 프로그래밍

임베디드 프로그래밍. Lecture #04 2018. 10. 30. 목 차. 아날로그 입 출 력 테스트 I2C 통신 테스트 SPI 통신 테스트. 아날로그 입출력 (1). 아날로그 입력 대부분의 저항성 센서는 아날로그 신호로 측정값을 출력 저항성 센서의 기본 회로 : 저항병렬연결의 분압 원리 이용 센서값 처리를 위해서는 아날로그 신호의 디지털 값으로 변환 필요 ADC(Analog-to-Digital Converter). 고정 저항. 저항성 센서. Vcc. GND. 센서값 측정.

cirvine
Download Presentation

임베디드 프로그래밍

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 임베디드 프로그래밍 Lecture #04 2018. 10. 30

  2. 목 차 • 아날로그 입출력 테스트 • I2C 통신 테스트 • SPI 통신 테스트

  3. 아날로그 입출력 (1) • 아날로그 입력 • 대부분의 저항성 센서는 아날로그 신호로 측정값을 출력 • 저항성 센서의 기본 회로: 저항병렬연결의 분압 원리 이용 • 센서값 처리를 위해서는 아날로그 신호의 디지털 값으로 변환 필요 • ADC(Analog-to-Digital Converter) 고정 저항 저항성 센서 Vcc GND 센서값 측정

  4. 아날로그 입출력 (2) • 아날로그 출력 • 대부분의 액츄에이터(Actuator) 장치는 아날로그 신호로 제어 • 예: • 서보 모터/ DC 모터 속도 제어 • LED 밝기 제어 등 • 디지털 값을 아날로그 신호로 변환하는 장치가 필요 • Hardware PWM • Software PWM • DAC(Digital-to-Analog Converter)

  5. 아날로그 입출력 (3) • 라즈베리파이의 아날로그 입출력 (1) • 라즈베리파이는ADC/DAC 장치를 지원하지 않는다  라즈베리파이만으로는 아날로그 입출력을 수행하지 못함. • 별도의 ADC/DAC 장치를 이용하여 아날로그 입출력 처리 • MCP4911, MCP3002, PCF8591 등 • 외부 ACD/DAC와 라즈베리파이 사이의 인터페이스(통신방식) • I2C(Inter-IC) • SPI(Serial Peripheral Interface)

  6. 아날로그 입출력 (4) • 라즈베리파이의 아날로그 입출력 (2) ADC Sensors RaspberryPi I2C / SPI Actuator DAC

  7. 아날로그 입출력 (5) • I2C(Inter-IC) 시리얼 통신 • 단방향 동기식 직렬 통신

  8. 아날로그 입출력 (6) • SPI(Serial Peripheral Interface) 시리얼 통신 • 양방향 동기식 직렬 통신

  9. 아날로그 입출력 (7) • PCF8591 Breakout Board • PCF8591T : 8-bit AD-DA Converter / I2C Interface

  10. 아날로그 입출력 (8) • PCF8591 Breakout Board • PCF8591T Spec: • Addressing: • Control byte: A2: High, A1: Low A0: Low => 주소: 0x48

  11. 아날로그 입출력 (9) • PCF8591 Breakout Board • Jumper Setting • AIN0 <-->INPUT0(Potentiometer) • AIN1 <-->INPUT1(Photoresistor) • AIN2 <-->INPUT2(Themistor) • AIN3 • AOUT

  12. 아날로그 입출력 (10) • PCF8591 Breakout Board 연결 • 라즈베리파이와의 연결 • DAC 테스트 연결 Pin 3 Pin 5 Pin 1 Pin 9 실습키트LED S1 AOUT GND

  13. 아날로그 입출력(11) • 라즈베리파이의I2C Bus 설정 (1) • 라즈베리파이 설정 유틸리티 “raspi-config”을 이용하여 I2C 장치를 사용 가능하도록 설정 # sudoraspi-config • I2C Tool 설치 # sudo apt-get install i2c-tools • I2C 사용자 그룹에 “pi” user 추가 # sudoadduser pi i2c

  14. 아날로그 입출력(12) • 라즈베리파이의I2C Bus 설정(2) • I2C Tool 테스트 및 i2c slave 장치 주소 확인 # sudo i2cdetect –l // i2c 장치 목록 확인 # sudo i2cdetect –y 1 PCF8591 Breakout board의 주소는 0x48

  15. 아날로그 입출력(13) • I2C Bus 입출력 테스트 (1) • PCF8591 AIN0 값 읽기 # sudoi2cset –y 1 0x48 0x00 // send control byte to read AIN0(Potentiometer) # sudo i2cget –y 1 0x48 // read one byte from bus 1 dev 0x48 # sudo i2cget –y 1 0x48 # sudo i2cget –y 1 0x48 샘플링 지연으로 인해 첫 번째 읽은 값과 두 번째 읽은 값이 다를 수 있음

  16. 아날로그 입출력(14) • I2C Bus 입출력 테스트 (2) • PCF8591 AIN1 값 읽기 # sudoi2cset –y 1 0x48 0x01 // set control byte to read AIN1(Photoresistor) # sudo i2cget –y 1 0x48 // read one byte from bus 1 dev 0x48 # sudo i2cget –y 1 0x48 # sudo i2cget –y 1 0x48

  17. 아날로그 입출력(15) • I2C Bus 입출력 테스트 (3) • PCF8591 AOUT(PWM) 출력 # sudo i2cset –y 1 0x48 0x40 0xff // set a value 0xff to AOUT # sudo i2cset –y 1 0x48 0x40 0xc0// set a value 0xc0 to AOUT # sudo i2cset –y 1 0x48 0x40 0x90// set a value 0x90 to AOUT # sudo i2cset –y 1 0x48 0x40 0x00// set a value 0x00 to AOUT PCF8591 Breakout 보드 위의 LED 밝기 변화를 확인

  18. 아날로그 입출력 (16) • PCF8591 Breakout Board 테스트 (1) • NetBeans IDE를 이용한 테스트 프로그램 작성 및 테스트 • 아날로그 입력값을 읽어 화면에 출력 • 아날로그 출력을 이용하여 LED Dimming • NetBeans IDE에서 새로운 프로젝트 생성 • 프로젝트명: jiot04_PCF8591BB_test • Main Class Name: jiot04.pcf8591bb_test.PCF8591BBTest • 프로젝트 속성 설정에서 라이브러리 추가 • dio.jar 라이브러리 추가

  19. 아날로그 입출력 (17) • PCF8591 Breakout Board 테스트 (2) • jdk.dio.i2cdev 패키지를 이용하여 I2C 장치 드라이브 구현 • “source packages” 내에 “i2c_dev” 패키지 생성 • “i2c_dev” 패키지 내에 다음의 클래스 파일 생성 • I2CRPi.java – I2C Device wrapper class • I2CUtils.java – I2C Device I/O utility method(static method) 지원 • PCF8591.java – PCF8591 IC의 register I/O enumerator 객체 정의

  20. 아날로그 입출력 (18) • PCF8591 Breakout Board 테스트 (3) • i2c_dev.I2CRPi.java package i2c_dev; import java.io.IOException; import jdk.dio.DeviceManager; import jdk.dio.i2cbus.I2CDevice; import jdk.dio.i2cbus.I2CDeviceConfig; public class I2CRPi { private I2CDeviceConfig config; public I2CDevice device = null; public I2CRPi(int i2cAddress) throws IOException { config = new I2CDeviceConfig.Builder() .setAddress(i2cAddress, I2CDeviceConfig.ADDR_SIZE_7) .build(); device = (I2CDevice) DeviceManager.open(I2CDevice.class, config); } public void close() { try { device.close(); } catch (IOException ex) { ex.printStackTrace(); } } }

  21. 아날로그 입출력 (19) • PCF8591 Breakout Board 테스트 (4) • i2c_dev.I2CUtils.java package i2c_dev; import java.io.IOException; import java.nio.ByteBuffer; import jdk.dio.i2cbus.I2CDevice; /** * Functions to read and write to I2C Raspberry Pi bus * */ public class I2CUtils { /** * * @parammili */ public static void I2Cdelay(intmili) { try { Thread.sleep(mili); } catch (InterruptedException ex) { } } /** * @parammili * @paramnano */ public static void I2CdelayNano(intmili, intnano) { try { Thread.sleep(mili, nano); } catch (InterruptedException ex) { } } /** * @param b * @return byte values from -127..128 convert 128..255 */ public static intasInt(byte b) { inti = b; if (i < 0) { i += 256; } return i; }

  22. /** * @param device Device connected to I2C bus * @paramcmd Command send to device * @return read an int from a device connected to I2C bus */ public static int read(I2CDevice device, intcmd) { ByteBufferrxBuf = ByteBuffer.allocateDirect(1); try { device.read(cmd, 1, rxBuf); } catch (IOException ex) { //Logger.getGlobal().log(Level.WARNING,ex.getMessage()); //ex.printStackTrace(); System.out.println("WARNING: " + ex.getMessage()); } return asInt(rxBuf.get(0)); } /** * @param device Device connected to I2C bus * @paramcmd Command send to Arduino Due * @return read a float from Arduino Due connected to I2C bus. All bytes * received must be swamp order */ public static float readFloatArduino(I2CDevice device, intcmd) { byte[] b = new byte[4]; ByteBufferrxBuf = ByteBuffer.allocateDirect(4); try { device.read(cmd, 4, rxBuf); } catch (IOException ex) { //Logger.getGlobal().log(Level.WARNING, ex.getMessage()); System.out.println("WARNING: " + ex.getMessage()); } rxBuf.clear(); for (inti = 0; i < 4; i++) { b[i] = rxBuf.get(3 - i); } return ByteBuffer.wrap(b).getFloat(); } /** * @param device Device connected to I2C bus * @paramcmd Command send to Arduino Due * @return read a short from Arduino Due connected to I2C bus. All bytes * received must be swamp order */ public static short readShortArduino(I2CDevice device, intcmd) { byte[] b = new byte[2]; ByteBufferrxBuf = ByteBuffer.allocateDirect(2); try { device.read(cmd, 2, rxBuf); } catch (IOException ex) { //Logger.getGlobal().log(Level.WARNING, ex.getMessage()); System.out.println("WARNING: " + ex.getMessage()); } rxBuf.clear(); for (inti = 0; i < 2; i++) { b[i] = rxBuf.get(1 - i); } return ByteBuffer.wrap(b).getShort(); } /** * @param device Device connected to I2C bus * @paramcmd Command send to a device * @return read a short from a device connected to I2C bus */ public static short readShort(I2CDevice device, intcmd) { //byte[] b = new byte[2]; ByteBufferrxBuf = ByteBuffer.allocateDirect(2);

  23. try { device.read(cmd, 1, rxBuf); } catch (IOException ex) { //Logger.getGlobal().log(Level.WARNING, ex.getMessage()); System.out.println("WARNING: " + ex.getMessage()); } rxBuf.clear(); return rxBuf.getShort(); } /** * @param device Device connected to I2C bus * @paramcmd Command send to a device * @param value Command value to wite to device */ public static void write(I2CDevice device, byte cmd, byte value) { ByteBuffertxBuf = ByteBuffer.allocateDirect(2); txBuf.put(0, cmd); txBuf.put(1, value); try { device.write(txBuf); } catch (IOException ex) { //Logger.getGlobal().log(Level.WARNING, ex.getMessage()); System.out.println("WARNING: " + ex.getMessage()); } } /** * Write multiple bits in an 8-bit device register. * @paramdevAddr I2C slave device address * @paramregAddr Register regAddr to write to * @parambitStart First bit position to write (0-7) * @param length Number of bits to write (not more than 8) * @param data Right-aligned value to write */ public static void writeBits(I2CDevice devAddr, byte regAddr, intbitStart, int length, int data) { // 010 value to write // 76543210 bit numbers // xxx args: bitStart=4, length=3 // 00011100 mask byte // 10101111 original value (sample) // 10100011 original & ~mask // 10101011 masked | value byte b = (byte) read(devAddr, regAddr); if (b != 0) { int mask = ((1 << length) - 1) << (bitStart - length + 1); data <<= (bitStart - length + 1); // shift data into correct position data &= mask; // zero all non-important bits in data b &= ~(mask); // zero all important bits in existing byte b |= data; // combine data with existing byte write(devAddr, regAddr, b); } } /** * write a single bit in an 8-bit device register. * * @paramdevAddr I2C slave device address * @paramregAddr Register regAddr to write to * @parambitNum Bit position to write (0-7) * @param data */ public static void writeBit(I2CDevice devAddr, byte regAddr, intbitNum, int data) { int b= (byte) read(devAddr, regAddr); b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum)); write(devAddr, regAddr, (byte) b); } }

  24. 아날로그 입출력 (20) • PCF8591 Breakout Board 테스트 (5) • i2c_dev.PCF8591.java package i2c_dev; import jdk.dio.i2cbus.I2CDevice; public enum PCF8591 { /** * Analog Input 0 */ AIN0(0x0), /** * Analog Input 1 */ AIN1(0x01), /** * Analog Input 2 */ AIN2(0x02), /** * Analog Input 3 */ AIN3(0x03), /** * Analog Output */ AOUT(0x40); /** * */ public byte cmd; private PCF8591(intcmd) { this.cmd = (byte) cmd; } /** * @param device * @return */ public int read(I2CDevice device) { return I2CUtils.read(device, this.cmd); } /** * @param device * @param value */ public void write(I2CDevice device, int value) { I2CUtils.write(device, this.cmd, (byte)value); } }

  25. 아날로그 입출력 (21) • PCF8591 Breakout Board 테스트 (6) • 앞에서 구현한 I2C 장치 인터페이스 클래스를 이용하여 PCF8591 장치 드라이브 구현 • “source packages” 내에 “i2c_dev.drivers” 패키지 생성 • “i2c_dev.drivers” 패키지 내에 다음의 클래스 파일 생성 • PCF8591Device.java – PCF8591 IC의 장치 드라이브 클래스

  26. 아날로그 입출력 (22) • PCF8591 Breakout Board 테스트 (7) • i2c_dev.drivers.PCF8591Device.java switch (ainPin) { case 0: value = PCF8591.AIN0.read(device); break; case 1: value = PCF8591.AIN1.read(device); break; case 2: value = PCF8591.AIN2.read(device); break; case 3: value = PCF8591.AIN3.read(device); break; } return value; } public void analogWrite(intpwm) throws IOException { PCF8591.AOUT.write(device, pwm); } } package i2c_dev.drivers; import i2c_dev.I2CRPi; import i2c_dev.PCF8591; import java.io.IOException; public class PCF8591Device extends I2CRPi { private static final int PCF8591Addr = 0x48; public PCF8591Device() throws IOException { super(PCF8591Addr); device.write(0x00); } public intanalogRead(intainPin) { int value = 0;

  27. 아날로그 입출력 (23) • PCF8591 Breakout Board 테스트 (8) • PCF8591 장치 테스트 프로그램 구현 • Pcf8591bb_test.PCF8591Test.java • 아날로그 입력 0~3을순서대로 읽어 화면에 출력 • 아날로그 출력을 이용하여 LEDdimming

  28. System.out.println("LED dimming..."); adConverter.analogWrite(0xff); I2CUtils.I2Cdelay(3000); adConverter.analogWrite(0xcf); I2CUtils.I2Cdelay(3000); adConverter.analogWrite(0xaf); I2CUtils.I2Cdelay(3000); adConverter.analogWrite(0x9f); I2CUtils.I2Cdelay(3000); adConverter.analogWrite(0x00); } catch (IOException ex) { System.out.println("ERROR: " + ex.getMessage()); } } // main() } package pcf8591bb_test; import i2c_dev.I2CUtils; import i2c_dev.drivers.PCF8591Device; import java.io.IOException; public class I2CTest { public static void main(String[] args) { try { PCF8591Device adConverter = new PCF8591Device(); adConverter.analogRead(0); I2CUtils.I2Cdelay(1000); adConverter.analogRead(0); I2CUtils.I2Cdelay(1000); System.out.println("Potentimeter Input : " + adConverter.analogRead(0)); I2CUtils.I2Cdelay(1000); adConverter.analogRead(1); I2CUtils.I2Cdelay(1000); System.out.println("Photoregister Input : " + adConverter.analogRead(1)); I2CUtils.I2Cdelay(1000); adConverter.analogRead(2); I2CUtils.I2Cdelay(1000); System.out.println("Themistor Input : " + adConverter.analogRead(2)); I2CUtils.I2Cdelay(1000);

  29. 아날로그 입출력 (24) • PCF8591 Breakout Board 테스트 (9) • 설정 파일 추가 • “lib” 디렉토리 추가 • 장치 레지스트리 파일 및 보안 정책 파일 추가 • build.xml 파일 수정

  30. 아날로그 입출력 (25) • PCF8591 Breakout Board 테스트 (10) • 설정 파일 – 장치 레지스트리 파일 • 본 예제에서는 프로그램 내에서 장치 설정을 동적으로 수행하기 때문에 장치 레지스트리 파일 내용이 영향을 미치지 않는다. # RPi3 header pins 1 = deviceType: gpio.GPIOPin, pinNumber:4, name:GPIO4, predefined:true 2 = deviceType: gpio.GPIOPin, pinNumber:7, name:GPIO7, mode:4, direction:1, predefined:true #3 = deviceType: gpio.GPIOPin, pinNumber:17, name:GPIO17, predefined:true 17 = deviceType: gpio.GPIOPin, pinNumber:17, name:GPIO17, mode:4, direction:1, predefined:true 4 = deviceType: gpio.GPIOPin, pinNumber:18, name:GPIO18, mode:4, direction:1, predefined:true 5 = deviceType: gpio.GPIOPin, pinNumber:22, name:GPIO22, predefined:true 6 = deviceType: gpio.GPIOPin, pinNumber:23, name:GPIO23, mode:2, direction:0, predefined:true 7 = deviceType: gpio.GPIOPin, pinNumber:24, name:GPIO24, mode:2, direction:0, predefined:true …

  31. 아날로그 입출력 (26) • PCF8591 Breakout Board 테스트 (11) • 설정 파일 – 보안 정책 파일 // policy for DIO framework grant { // Very permissive permissions permission jdk.dio.DeviceMgmtPermission "*:*", "open"; permission jdk.dio.gpio.GPIOPinPermission "*:*"; permission jdk.dio.i2cbus.I2CPermission "*:*"; permission jdk.dio.spibus.SPIPermission "*:*"; };

  32. 아날로그 입출력 (27) • PCF8591 Breakout Board 테스트 (12) • build.xml 파일 수정 lib

  33. 아날로그 입출력 (28) • PCF8591 Breakout Board 테스트 (13) • 프로젝트 속성 설정 수정 • Sources / Run 속성 수정

  34. 아날로그 입출력 (29) • PCF8591 Breakout Board 테스트 (14) • 원격 실행 • 원격 디버깅

More Related